【EFCore】笔记17 批量处理

/ 0评 / 0

直到 EFCore 6,微软官方还没有提供对高效批量处理的支持。以删除数据为例,无论是在循环中使用 Delete 方法,还是使用 DeleteRange 方法,EFCore 都只会生成很多条 Delete 语句来逐个删除,而这些批量删除的需求往往通过一条 SQL 语句就能完成。

虽然不知道未来 EFCore 7 是否会支持批量处理,但目前已经有许多开源库提前实现了。这里要介绍的是杨中科老师完成的项目 Zack.EFCore.Batch,这个库支持在 EFCore 里批量插入(BulkInsert)、删除、更新,并且让程序员依旧能够只编写 C# 代码而不是 SQL 脚本。

在项目主页有中英文的使用教程,并且持续更新,这里就不重复了。下面演示一个例子:将价格低于 50 的所有 Book 打 8 折。

常规做法会让 EFCore 生成很多 UPDATE 语句(取决于记录的数量):

using (MyDbContext ctx = new MyDbContext())
{
    var books = ctx.Books.Where(e => e.Price < 50);
    foreach (var book in books)
    {
        book.Price *= 0.8;
    }
    await ctx.SaveChangesAsync();
}

使用 Zack.EFCore.Batch 的做法如下:

using (MyDbContext ctx = new MyDbContext())
{
    await ctx.BatchUpdate<Book>().Where(e => e.Price < 50)
        .Set(e => e.Price, e => e.Price * 0.8)
        .ExecuteAsync();
}

生成的 SQL 语句如下:

Update [T_Books] SET [Price] = [Price] * 0.80000000000000004E0
WHERE [Id] IN(SELECT [Id] FROM (SELECT [t].[Id], [t].[Price], [t].[Time], [t].[Title]
FROM [T_Books] AS [t]
WHERE [t].[Price] < 50.0E0)  AS  temp1 )

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *