前言
Entity Framework Core(EF Core)作為 .NET 生態系統中受歡迎的物件關係對映器(ORM),其輕量級、可擴充套件性和支援多個資料庫引擎而備受青睞。
本文將介紹一款.NET 的開源 EF Core 批處理擴充套件工具,它極大地提升了資料處理的效率和效能。來看看如何輕鬆整合到我們現有的 EF Core 專案中。
EFCore.BulkExtensions
Entity Framework Core (EF Core) 批次擴充套件庫提供了支援批次複製功能的工具,適用於 .NET 平臺上的插入、更新、刪除、讀取(CRUD)、清空表(Truncate)以及儲存更改(SaveChanges)等操作。
該庫支援 SQL Server、PostgreSQL、MySQL 和 SQLite 資料庫。
該庫輕量且高效,涵蓋了常用的 CRUD 操作,並被微軟評為推薦的前 20 個 EF Core 擴充套件之一。
版本說明
內部機制
SQL Server:使用 SqlBulkCopy 進行插入操作,更新和刪除操作則結合了 BulkInsert 和原生 SQL 的 MERGE。
SQLite:由於沒有 BulkCopy,該庫使用純 SQL 結合 UPSERT。
注意事項
批次測試:不能使用 UseInMemoryDb,因為 InMemoryProvider 不支援特定的關聯式資料庫方法。
如何使用?
首先使用 Nuget 安裝 EFCore.BulkExtensions。
Install-Package EFCore.BulkExtensions
批次操作示例
context.BulkInsert(entities);
context.BulkInsertOrUpdate(entities);
context.BulkInsertOrUpdateOrDelete(entities);
context.BulkUpdate(entities);
context.BulkDelete(entities);
context.BulkRead(entities);
context.BulkSaveChanges();
非同步版本
context.BulkInsertAsync(entities); context.BulkInsertOrUpdateAsync(entities); //Upsert context.BulkInsertOrUpdateOrDeleteAsync(entiti);//Sync context.BulkUpdateAsync(entities); context.BulkDeleteAsync(entities); context.BulkReadAsync(entities); context.BulkSaveChangesAsync();
與 EF Core 使用
// 刪除 context.Items.Where(a => a.ItemId > 500).BatchDelete(); context.Items.Where(a => a.ItemId > 500).BatchDeleteAsync(); // 更新 context.Items.Where(a => a.ItemId <= 500).BatchUpdate(a => new Item { Quantity = a.Quantity + 100}); context.Items.Where(a => a.ItemId <= 500).BatchUpdateAsync(a => new Item {Quantity=a.Quantity+100}); // can be as value '+100' or as variable '+incrementStep' (int incrementStep = 100;) // 更新 context.Items.Where(a => a.ItemId <= 500).BatchUpdate(new Item { Description = "Updated" }); context.Items.Where(a => a.ItemId <= 500).BatchUpdateAsync(new Item { Description = "Updated" }); // Truncate context.Truncate<Entity>(); context.TruncateAsync<Entity>();
批次操作
連線字串配置
如果使用 Windows 身份驗證,則連線字串中應包含 Trusted_Connection=True,因為 SQL 身份驗證資訊需要保留在連線中。
事務管理
每個批次操作預設作為單獨的事務處理,並自動提交。如果需要在一個過程中執行多個操作,則應顯式使用事務。
例如,由於子表不會自動與父表一起插入,因此需要顯式進行第二次呼叫:
using (var transaction = context.Database.BeginTransaction()) { context.BulkInsert(entitiesList); context.BulkInsert(subEntitiesList); transaction.Commit(); }
批次插入或更新
BulkInsertOrUpdate 方法適用於需要在同一資料庫連線中執行插入或更新操作的場景。當主鍵(Primary Key)匹配時執行更新,否則執行插入。
批次插入、更新或刪除
BulkInsertOrUpdateOrDelete 方法有效地同步表中的行與輸入資料。不在輸入列表中的資料庫記錄將被刪除。
批次讀取
BulkRead 方法基於一個或多個唯一列執行 SELECT 和 JOIN 操作,這些列在配置的 UpdateByProperties 中指定。
示例
using (var transaction = context.Database.BeginTransaction()) { // 插入或更新主表 context.BulkInsertOrUpdate(mainEntitiesList); // 插入或更新子表 context.BulkInsertOrUpdate(subEntitiesList); // 提交事務 transaction.Commit(); } // 同步錶行與輸入資料 context.BulkInsertOrUpdateOrDelete(allEntitiesList); // 根據唯一列讀取資料 context.BulkRead(uniqueColumnsConfig);
效能測試結果
以下是在 SQL Server 2019 上進行的效能測試結果(單位:秒):
測試配置
硬體配置:Intel i7-10510U CPU @ 2.30GHz, DDR3 16GB, SSD Samsung 512GB
測試表結構:測試表 TestTable 包含 6 列(Guid, string x2, int, decimal?, DateTime),所有列均被插入,其中 2 列被更新
效能對比
注意事項
小資料集開銷:對於較小的資料集(少於 1000 行),由於大多數批次操作需要建立臨時表並在完成後刪除臨時表,因此會有一定的開銷。
建議:建議對於大於 1000 行的資料集使用批次操作以獲得最佳效能。
專案地址
https://github.com/borisdj/EFCore.BulkExtensions
總結
希望本文能為朋友們在使用EF Core開發方面帶來幫助。歡迎大家在評論區留言討論,分享您的經驗和建議。
如果你覺得這篇文章對你有幫助,不妨點個贊支援一下!你的支援是我繼續分享知識的動力。如果有任何疑問或需要進一步的幫助,歡迎隨時留言。
也可以加入微信公眾號[DotNet技術匠] 社群,與其他熱愛技術的同行一起交流心得,共同成長!優秀是一種習慣,歡迎大家留言學習!