GZY.EFCore.BulkExtensions 支援達夢資料庫的EF Core批次操作庫詳解

GuZhenYin發表於2024-12-05
前言

EFCore.BulkExtensions是一個常用的EF core 批次處理資料的庫.

但是支援的資料庫相對較少.特別是.NET5.0版本 連MySQL都無法支援

這個庫就是改造的最新EFCore.BulkExtensions的程式碼

讓它能在.NET5.0中支援Mysql和達夢資料庫

由於5.0在升到最新9.0的過程中有比較重大的改變,所以.NET8+的 我還在弄..估計後面支援吧

詳細說明

使用方法如下:

 using (TestDbContext ctx = new TestDbContext())
 {
     List<Book> books2 = TestBulkInsert1.BuildBooks();
     ctx.BulkInsert(books2); //批次插入

     var book3 = ctx.Books.Take(1000).ToList();
     ctx.BulkDelete(book3); //按實體批次刪除
     ctx.Books.Where(a => a.BookType == BookType.Fictional).BatchDelete(); //按條件刪除

     ctx.Books.Where(a => a.BookType == BookType.Scientific).BatchUpdate(a => new Book { Price = a.Price + 50, AuthorName = "gzy666" }); //批次按條件更新
                                                                                                                                      
     var list = ctx.Books.Take(5000).ToList();
     list.ForEach(a => a.AuthorName = "gzy8998");
     ctx.BulkUpdate(list);  //按實體批次更新
 }

比較實用的是批次按實體進行修改、批次按實體刪除、批次插入

7.0+雖然支援了按條件進行修改和刪除但是批次處理 還是並未支援.

主要講解一下兩個資料庫的實現原理吧

1.MySql的實現方式

1.1批次插入

這其實就不用介紹了,就是最常見的SqlBulkCopy的形式進行資料匯入

優點就是量大管飽,速度快

缺點就是已經脫離了執行SQL的範疇,所以在實體監聽這些處理會比較麻煩

注意:Mysql使用SqlBulkCopy需要開啟local_infile功能,並需要在連線字串中配置:AllowLoadLocalInfile=true;

1.2批次修改

採用了Mysql的 on duplicate key update 語法進行批次處理

首先會建立臨時表,然後透過SqlBulkCopy將資料批次匯入至臨時表中

然後透過 解析實體產生 on duplicate key update 語法

類似如下SQL:

INSERT INTO my_table (column1, column2)
SELECT column1 FROM TempTableName AS EXCLUDED 
ON DUPLICATE KEY UPDATE
<column1> = <value1>, <column2> = <value2>;

它會透過主鍵來判斷資料是否更新,然後從臨時表中將資料更新過去

最後會刪除臨時表,(mysql也可以配置為會話臨時表,這樣就不用手動刪除,會話結束了 會自動刪除)

1.3批次刪除

採用了 DELETE INNER JOIN 語法進行批次處理

同樣也是將資料匯入至臨時表中,但是這裡做了一些最佳化,只匯入主鍵ID,因為刪除只需要主鍵即可

最後會生成類似SQL:

DELETE A
FROM {tableInfo.FullTableName} AS A
INNER JOIN {tableInfo.FullTempTableName} B on A.{firstPrimaryKey} = B.{firstPrimaryKey}; 

這樣就可以快速的進行批次刪除.

2.達夢資料庫的實現方式

2.1批次插入

其實國產的達夢資料庫也提供了對應的SqlBulkCopy類,DmBulkCopy,我們直接按規範實現即可

(注意:達夢資料庫的DmBulkCopy,暫時只提供了同步的方法,所以並不支援async非同步處理)

2.2批次修改

批次修改的語法達夢就與Mysql差異較大了,但是也提供了對應的SQL

達夢採用 MERGE INTO的語法 可以從臨時表中將資料批次更新至源表

2.3批次刪除

批次刪除也和Mysql大同小異

最後會生成類似如下SQL:

DELETE FROM
{tableInfo.FullTableName} AS A 
WHERE A.{firstPrimaryKey} IN
(SELECT B.{firstPrimaryKey} FROM {tableInfo.FullTempTableName} AS B )

從臨時表中根據主鍵刪除源表的資料.

相關文章