GZY.EFCore.BulkExtensions 支持达梦数据库的EF Core批量操作库详解

前言

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 )

从临时表中根据主键删除源表的数据.