.NET 開源 EF Core 批處理擴充套件工具,真好用

小码编匠發表於2024-09-30

前言

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 擴充套件之一。

版本說明

.NET 開源 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技術匠] 社群,與其他熱愛技術的同行一起交流心得,共同成長!優秀是一種習慣,歡迎大家留言學習!

相關文章