今天連假,終於有時間寫匯入功能
我需要的匯入功能,最基本的就是將文章資料匯到新資料庫裡就好。
先定義了 ImportPost.cs 來做為 Wordpress 文章資料格式。
public class ImportPost
{
public int ID { get; set; }
public int post_author { get; set; }
public DateTime post_date { get; set; }
public string post_content { get; set; }
public string post_title { get; set; }
public string post_excerpt { get; set; }
public string post_status { get; set; }
public string comment_status { get; set; }
public string ping_status { get; set; }
public string post_password { get; set; }
public string post_name { get; set; }
public string to_ping { get; set; }
public string pinged { get; set; }
public DateTime post_modified { get; set; }
public string post_content_filtered { get; set; }
public int post_parent { get; set; }
public string guid { get; set; }
public int menu_order { get; set; }
public string post_type { get; set; }
public string post_mime_type { get; set; }
public long comment_count { get; set; }
}
wordpress 的文章的設定,如圖片看可以有非常多的狀態。
去資料庫看是以 post_type
與 post_status
兩者構成文章狀態
目前資料中 Wordpress 的 posts 中所擁有的 post_type 為以下幾個
post_status 為以下幾個
我的新部落格只有 Status 來管理文章狀態
public enum PostStatus
{
草稿,
已發佈,
編輯紀錄,
已下架,
已刪除
}
所幸檢視了我現有的 wordpress 資料,其文章狀態很單純,所以我只要區分出 草稿
已發佈
編輯紀錄
三個狀態就好,就能匯入到我的新部落格中。
post_type | post_status | |
---|---|---|
草稿 | post | draft |
已發佈 | post | publish |
編輯紀錄 | revision | inherit |
public string GetStatus(ImportPost import)
{
if (import.post_type == "revision" && import.post_status == "inherit")
{
return PostStatus.編輯紀錄.ToString();
}
if (import.post_type == "post" && import.post_status == "draft")
{
return PostStatus.草稿.ToString();
}
if (import.post_type == "post" && import.post_status == "publish")
{
return PostStatus.已發佈.ToString();
}
return string.Empty;
}
轉換器只要把每一列資料換成現有 Post
格式,做新增就可以了。這邊要注意記得關掉資料庫的自動產生編號
private List<Post> ConvertToPosts(List<ImportPost> imports)
{
var list = new List<Post>();
foreach (var import in imports)
{
var result = ConvertToPost(import);
if (result != null)
{
list.Add(result);
}
}
return list;
}
private Post? ConvertToPost(ImportPost import)
{
var status = GetStatus(import);
if (string.IsNullOrWhiteSpace(status))
{
return null;
}
var post = new Post();
post.Id = import.ID;
post.UserId = import.post_author;
post.Title = import.post_title;
post.Content = import.post_content;
post.FilteredContent = import.post_content_filtered;
post.PublishDate = import.post_date;
post.UpdateDate = import.post_modified;
post.ParentId = import.post_parent;
post.Status = status;
post.Path = import.post_name;
return post;
}
這邊我使用 csv 格式靜態檔案的方式,來匯入資料。如果你使用其他格式,可以自己實作。
NuGet 安裝 CsvHelper
實作讀取器
private List<ImportPost> ReadData(IFormFile file)
{
var list = new List<ImportPost>();
switch (file.ContentType)
{
case "text/csv":
list = CsvReader(file);
break;
}
return list;
}
private List<ImportPost> CsvReader(IFormFile file)
{
if (file == null || file.Length == 0)
{
return new List<ImportPost>();
}
using (var reader = new StreamReader(file.OpenReadStream()))
using (var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)))
{
var records = csv.GetRecords<ImportPost>().ToList();
return records ?? new List<ImportPost>();
}
}
整個程式執行,讀資料 -> 格式轉換 -> 寫入 ,另外要注意在匯入的過程中,需要關閉資料庫 Post 的自動產生編號功能,變成 PostService 那邊要自己產生ID。
public async Task Start(IFormFile file)
{
if (file == null || file.Length == 0)
{
return;
}
var imports = ReadData(file);
var posts = ConvertToPosts(imports);
await CreatePostAsync(posts);
}
private async Task CreatePostAsync(List<Post> posts)
{
foreach (var post in posts)
{
await _postRepository.CreateAsync(post);
}
_postRepository.UnitOfWork.Save();
}
匯入成功後,就可以在首頁看到文章,大致上是這樣,有一些匯入細節我看看要不要明天再講
詳細程式碼可以到 GitHub 看