当前位置: 首页 > news >正文

Z.EntityFramework.Extensions.EFCore 批量更新(BulkUpdate)指定字段

Z.EntityFramework.Extensions.EFCore 批量更新(BulkUpdate)指定字段

一、Z.EntityFramework.Extensions.EFCore是什么?

Z.EntityFramework.Extensions.EFCore 是一个强大的第三方性能扩展库,专门为 Entity Framework Core 设计,用于弥补 EF Core 在批量操作方面的性能短板。


核心概念:解决 EF Core 的“痛点”

EF Core 是一个非常优秀的 ORM,它通过“变更跟踪器”来管理实体的状态。这在处理单个或少量实体时非常高效和方便。但是,当需要处理大量数据时,比如:

  • 删除所有过期的日志记录
  • 批量更新所有商品的价格
  • 从一个表向另一个表导入成千上万条数据

如果使用原生的 EF Core,你可能会这样写:

// 批量删除 - 原生EF Core方式(低效)
var oldLogs = dbContext.Logs.Where(x => x.CreatedDate < DateTime.Now.AddYears(-1));
dbContext.Logs.RemoveRange(oldLogs);
await dbContext.SaveChangesAsync();// 批量更新 - 原生EF Core方式(低效)
var products = dbContext.Products.Where(x => x.CategoryId == 1);
foreach (var product in products)
{product.Price *= 1.1m; // 涨价10%
}
await dbContext.SaveChangesAsync();

这种方式的问题在于:

  1. 删除:它会先将所有符合条件的数据从数据库查询出来,加载到内存中,并开始跟踪它们。然后标记为 Deleted,最后执行 SaveChanges 时,EF Core 会生成 N 条 独立的 DELETE SQL 语句(N是被删除的记录数)。
  2. 更新:同样,它先查询出所有数据,在内存中逐个修改,最后生成 N 条 独立的 UPDATE SQL 语句。

当 N 很大时(比如10万条),这个过程会消耗大量内存和网络资源,速度极慢,甚至可能导致应用程序崩溃。


Z.EntityFramework.Extensions.EFCore 的解决方案

这个库引入了批量操作的概念,它不通过 EF Core 的变更跟踪器,而是直接生成并执行一条高效的 SQL 语句。

主要功能:
  1. BulkDelete

    • 原理:根据你提供的条件(如 Where 语句),直接在数据库端生成并执行一条 DELETE ... WHERE ... 的 SQL。
    • 效果:无论删除多少条数据,都只在数据库端执行一次往返。
    // 使用 Z.EntityFramework.Extensions.EFCore 方式(高效)
    await dbContext.Logs.Where(x => x.CreatedDate < DateTime.Now.AddYears(-1)).BatchDeleteAsync();
    

    生成的SQL: DELETE FROM [Logs] WHERE [CreatedDate] < '2023-01-01'

  2. BulkUpdate

    • 原理:你提供一个需要更新的数据源(可以是查询结果,也可以是一个内存列表)和更新的规则,它生成一条 UPDATE ... SET ... WHERE ... 的 SQL。
    • 效果:一次数据库往返完成所有更新。
    // 使用 Z.EntityFramework.Extensions.EFCore 方式(高效)
    await dbContext.Products.Where(x => x.CategoryId == 1).BatchUpdateAsync(new Product { Price = Product.Price * 1.1m });
    

    生成的SQL: UPDATE [Products] SET [Price] = [Price] * 1.1 WHERE [CategoryId] = 1

  3. BulkInsert

    • 原理:将一个巨大的 List<T> 一次性插入数据库。相比于 EF Core 原生的 AddRangeAsync + SaveChangesAsync(会生成大量 INSERT 语句),它使用数据库原生的批量插入机制(如 SqlBulkCopy for SQL Server),速度极快。
    • 效果:性能比原生方式提升几个数量级。
    var massiveList = new List<Product>(); // 假设这里有10万个产品
    // ... 填充数据
    await dbContext.BulkInsertAsync(massiveList);
    
  4. BulkMerge (Upsert)

    • 这是一个更高级的功能,相当于 INSERT ... ON DUPLICATE KEY UPDATE(MySQL)或 MERGE(SQL Server)。如果记录存在则更新,不存在则插入。这在数据同步场景中非常有用。

优点

  • 极高的性能提升:在处理大量数据时,性能提升可达数十倍甚至数百倍。
  • 低内存消耗:避免了将大量数据加载到内存中。
  • 减少数据库压力:将多次往返减少为一次,并生成更高效的 SQL。
  • 易于使用:API 设计流畅,与 LINQ 无缝集成。

缺点与注意事项

  • 第三方库:这不是微软官方的包,需要信任并依赖第三方开发者。
  • 绕过变更跟踪器:因为它直接操作数据库,所以不会触发 EF Core 的变更跟踪器、SaveChanges 拦截器以及数据库的并发检查。如果你的业务逻辑严重依赖这些机制,需要谨慎使用。
  • 许可和成本:该库在早期版本通常是免费的,但对于新版本或高级功能,可能需要购买商业许可证。请务必查看其官方许可条款。

二、Z.EntityFramework.Extensions.EFCore 中的 BulkUpdate 方法支持更新指定字段

在更新数据库时指定字段(而不是更新所有字段)是一个非常常见的做法,在性能方便带来的巨大的优势。Z.EntityFramework.Extensions.EFCore 中的 BulkUpdate 方法支持更新指定字段。但不同版本的实现方式可能有所不同。 由于本人的版本是:Z.EntityFramework.Extensions.EFCore 5.17.2.0,这里我只介绍 Z.EntityFramework.Extensions.EFCore 5.17.2.0 支持的方式。

使用 ColumnInputExpression 指定更新字段

这是最直接和常用的方法,明确指定要更新的属性:

// 只更新 Name 和 Email 字段
dbContext.BulkUpdate<Customer>(customers, options => {options.ColumnInputExpression = m => new { m.Name, m.Email }; // 使用 lambda 表达式
});

如果你想要排除某些字段:

dbContext.BulkUpdate<Customer>(customers, options => {// 使用排除方式 - 先包含所有字段,然后排除不需要的options.ColumnInputExpression = m => m;options.IgnoreOnUpdateExpression = m => new { m.CreatedDate, m.IsDeleted };
});
http://www.dtcms.com/a/528392.html

相关文章:

  • MLLM-LLaVA-FL: Multimodal Large Language Model Assisted FederatedLearning
  • 欧美教育网站模板中国建设银行信用卡网站首页
  • 【同步 / 异步 日志系统】--- 全局接口 性能测试
  • GitHub等平台形成的开源文化正在重也有人
  • 03_Pushgateway使用Prometheus的服务发现机制
  • Speckit和Claude 的初体验
  • 当夸克遇上大模型:中国 AI 产品的“第二阶段”来临了
  • AI大模型弹性伸缩实战:自动扩缩容+模型轻量化+Serverless三大技术方案详解
  • 网站怎么做的qq邮件订阅页面设计存在的问题
  • CMP(类ClouderaCDP7.3(404次编译) )完全支持华为鲲鹏Aarch64(ARM),粉丝数超过200就开源下载
  • HeidiSQL的下载安装和使用
  • 线性代数直觉(五):行列式——让空间坍缩
  • word文档模板通过poi-tl导出问题注意点
  • Java在大数据分布式存储中的创新实践
  • ThinkPHP5 RCE+Linux find提权渗透实战:原理+复现(CVE-2018-20062)
  • 昆明网站排名优化电商网站的功能
  • 代码随想录Day59|dijkstra(堆优化版)精讲、Bellman_ford 算法精讲
  • 四川住建厅官方网站的网址教务管理系统学生登录入口
  • [MySQL]数据类型
  • 3w字一文讲透Java IO
  • 多模态学习大纲笔记(未完成)
  • 组织学习障碍:自我证明的陷阱
  • 【数据结构】顺序表的实现
  • 可以做兼职的网站质量好网站建设多少钱
  • 无声的战争:自动驾驶系统中的资源抢占、调度与生存法则
  • 30-机器学习与大模型开发数学教程-3-4 矩阵的逆与伪逆
  • 【大语言模型 104】LLM推理服务架构:从单机到分布式的演进之路
  • Rust所有权机制解析:内存安全的基石与实战指南
  • 个人做商业网站需要什么如何判断网站数据库类型
  • Spring容器进化论:从BeanFactory到ApplicationContext