Entity Framework Core 7中高效地進行批次資料插入

2022-12-01 12:00:47

因為之前的版本中,EF Core無法實現高效地批次插入、修改、刪除資料,所以我開發了Zack.EFCore.Batch這個開源專案,比較受大家的歡迎,獲得了400多個star。

從.NET 7開始,微軟在Entity Framework Core 7內建了對高效地批次修改、刪除資料的支援,詳細請見這個檔案 https://learn.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-7.0/whatsnew?WT.mc_id=DT-MVP-5004444 因此我的這個開源專案在.NET 7中將不再提供對批次修改、刪除資料的支援。但是由於Entity Framework Core中仍然沒有提供高效地批次插入資料的功能,因此我把這個開源專案升級到.NET 7,從而繼續為EF Core提供高效地批次插入資料的功能。

為什麼開發這個功能?

Entity Framework Core中可以通過AddRange()方法來批次插入資料,但是AddRange()新增的資料仍然是被逐條執行Insert語句來插入到資料庫中的,執行效率比較低。我們知道,我們可以通過SqlBulkCopy來快速地插入大量的資料到SQLServer資料庫,因為SqlBulkCopy是把多條資料打成一個封包傳送到SQLServer的,所以插入效率非常高。MySQL、PostgreSQL等也有類似的支援。

當然,直接使用SqlBulkCopy來進行資料插入需要程式設計師把資料填充到DataTable,而且需要進行列的對映等操作,還需要處理ValueConverter等問題,用起來比較麻煩。因此我對這些功能封裝,從而讓EF Core的開發者能夠更方便的以面向模型的方式來插入資料。

這個庫目前支援MS SQLServer、MySQL、PostgreSQL資料庫。

效能對比

我用SQLServer資料庫做了一下插入10萬條資料的測試,用AddRange插入耗時約21秒,而用我這個開源專案進行插入耗時只有約5秒。

專案用法

這個庫的舊版也支援.NET 5、6等版本,具體用法見https://github.com/yangzhongke/Zack.EFCore.Batch ,下面只講.NET 7中的用法。

首先,安裝Nuget包:

SQLServer使用者: Install-Package Zack.EFCore.Batch.MSSQL_NET7

MySQL使用者: Install-Package Zack.EFCore.Batch.MySQL.Pomelo_NET7

Postgresql使用者: Install-Package Zack.EFCore.Batch.Npgsql_NET7

然後就可以使用這個開源專案為DbContext提供的的擴充套件方法BulkInsert來進行資料的批次插入了,程式碼如下:

List<Book> books = new List<Book>();
for (int i = 0; i < 100; i++)
{
    books.Add(new Book { AuthorName = "abc" + i, Price = new Random().NextDouble(), PubTime = DateTime.Now, Title = Guid.NewGuid().ToString() });
}
using (TestDbContext ctx = new TestDbContext())
{
    ctx.BulkInsert(books);
}

開源專案地址: https://github.com/yangzhongke/Zack.EFCore.Batch

希望這個庫能幫到大家。

歡迎閱讀我編寫的《ASP.NET Core技術內幕與專案實戰》,這本書的宗旨就是「講微軟檔案中沒有的內容,講原理、講實踐、講架構」。感興趣請看右側公告。