查缺补漏系统学习 EF Core 6 - 批量操作

推荐关注「码侠江湖」星标,时刻不忘江湖事

这是 EF Core 系列的第七篇文章,上一篇文章讲述了 EF Core 中的实体数据修改。

这篇文章讲一讲 EF Core 如何进行批量操作。

在众多的 ORM 框架中,EF Core 的功能并不是最强大的那个,性能可能也不是最好的那个。但却一直是最稳定、最安全,扩展能力最强、使用人数最多的那个。

虽然在性能方面,在 EF Core 6.0 中已经得到了非常大的提升。

但是在功能方面, EF Core 一直有一个不完善的地方,就是它不能很好的支持数据的批量操作,也就是批量删除和批量更新。

所以这篇文章就先从比较常用的批量删除和批量更新讲起。

点击上方或后方蓝字,阅读 EF Core 系列合集。

1a684269619a8fd731a086a39615db20.png

批量操作

在 EF Core 中批量更新和删除数据,都需要先进行查询,把数据加载到内存中,然后再对数据操作,最后再SaveChanges 保存到数据库。

我们来看这个示例:

var accounts = _context.Accounts.Where(account => account.Age >= 1);foreach (var a in accounts)
{a.Age = a.Age + 1;
}_context.SaveChanges();

为了更新 Accounts 中实体的 Age 属性,我们必须查询出所有符合条件的实体集合,然后用遍历的方式,在内存中去逐个修改实体的 Age 属性。

最后,通过 SaveChanges 方法保存修改。

运行程序,结果如下图所示:

cce63becd4a126e8311b1d17e9203667.png

通过控制台日志可以发现,前后总共执行了 3 条 SQL 语句,1 条 Selet 语句和 2 条 Uptete 语句。

第一条 Selet 语句,是为了查询出所有符合条件的数据,由于数据库中只有 2 条数据,所以后面 2 条 Uptete 语句,是针对这 2 条数据的更新操作。

如果我们把更新操作换成删除操作,EF Core 也会如此去做。

大家可以想象一下,如果批量更新或者删除的数据量比较大,那么这样的操作,性能无疑是非常底下的。

因此,我们需要一种在 EF Core 中,只使用一条 SQL 语句,就可以批量删除或更新数据的方法。

由于这个功能确实比较常用,很多其它第三方的 ORM 框架,几乎也都支持这个操作。

但为什么作为 ORM 框架大佬的 EF Core,却不提供这个功能呢?

简单来说,EF Core 的开发团队认为,这样做会导致 EF Core 的对象状态跟踪混乱。

比如对于同一个上下文类,如果用批量删除的方法删除了数据,那么在被删除之前,查询出来的数据状态就混乱了。

毕竟,EF Core 是一个成熟且安全性高的 ORM 框架,必然会考虑潜在风险的存在。

如果想要完美实现,可能需要重构 EF Core 的代码,工作量方面会比较大。

但是,我们作为开发者,完全可以根据场景需求,来规避这些问题的存在。

比如在一个 Web 应用中,删除操作通常都是在一个 HTTP 请求中完成的,不同的 HTTP 请求上下文是不同的,所以基本不会涉及到 EF Core 开发团队担心的问题。

即便在某些特殊场景下,涉及到在同一个上下文里,数据删除之前就把数据查询出来的场景,那也完全可以通过在删除之后,再重新查询一次的方式,来规避这个问题。

未来 EF Core 会不会添加这个功能,我们不得而知,但我们也有自己的解决方法。

第一个解决方法,就是执行原生 SQL 语句,不过它的缺点我们在前面的文章中已经提过,就不再多说。

第二个解决方法,是使用第三方的 ORM 框架,比如 FreeSQL、SugarSQL,它们都提供了批量更新和批量删除的功能,使用起来也非常简单。

不过,这种方法的缺点就是必须在项目替换掉 EF Core ,使用第三方的 ORM 框架。

目前 EF Core 是 .NET 中,使用率最高的 ORM 框架,主打安全性与稳定性,而且 6.0 版本性能也得到了大量的改善,所以不建议轻易更换。

第三个解决方法,就是使用 EF Core 的扩展插件,由于 EF Core 在全球范围有着最多的用户基数,所以也形成了一个强大的生态环境,拥有很多的第三方扩展。

这同样也是第三方 ORM 框架,所无法比拟的地方。

我们可以在 EF Core 的官方文档,查阅到被官方收集的第三方扩展插件和工具。

这里面支持批量操作的扩展插件有两个:「EFCore.BulkExtensions」「Entity Framework Plus」

它们都支持最新的 EF Core,更新也比较稳定。

不同的是,E「FCore.BulkExtensions」 功能专一,仅扩展了批量操作方面的功能,同时也支持 「SqlBulkCopy」,也就是大数据量的批操作。

由于 「SqlBulkCopy」 只支持 SQLServer 和 SQLite ,所以 「EFCore.BulkExtensions」 只支持 SQLServer 和 SQLite。

「EF Plus」 功能更加强大,扩展了更多的查询功能,它分为免费版和收费版,基础的批量操作免费版就可以支持,高级批量操作以及 SqlBulkCopy 则只有收费版支持。

如果使用的是 MySQL,或者不需要 SqlBulkCopy,那么 「EF Plus 免费版」是首选,因为它支持更多的数据库,扩展了更丰富的查询功能。

安装好 EF Plus,这里我将刚才批量更新的操作,改为 EF Plus 来实现:

<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="6.13.19" />
_context.Accounts.Where(account => account.Age >= 1).Update(account => new Account {Age = account.Age + 1},update => update.Executing = command => Console.WriteLine(command.CommandText));

Update 就是 EF Plus 扩展的方法,它的第一个参数是要更新的数据,第二个参数是一个执行拦截器委托,这里用来打印准备执行的 SQL 语句。

现在运行程序,可以在控制台中看到:

679cd77da4480bc0290256ab0efcf701.png

执行的是 1 条 UPDATE 语句,这条 SQL 语句会更新所有 Accounts 中符合条件的 Age 字段。

除了批量更新,批量删除也同样简单。

更多的示例,大家可以看 EF Plus 的官网文档。

更多精彩内容,请关注我▼▼

3eeaf41a420eaa9b9ee0b76698ada1d6.gif

如果喜欢我的文章,那么

在看和转发是对我最大的支持!

(戳下面蓝字阅读)

e7167ee188e765616a3fa721635d064a.png

推荐关注微信公众号:码侠江湖

                        08863a258d6cbe8b39ed5ec759bb23d0.png觉得不错,点个在看再走哟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/287366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

半小时一篇文过完C语言基础知识点

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本文定位读者为小白读者&#xff0c;将使用最快的方法过完C语言基础知识…

php变量的判空和类型判断

&#xff08;1&#xff09;var_dump(); 判断一个变量是否已经声明并且赋值&#xff0c;并且打印类型和值 <?php $a; var_dump($a);//输出null<?php var_dump($a);//输出null<?php$a 10; var_dump($a);//输出 int 10&#xff08;2&#xff09;isset() 判断一个变量…

【Envi风暴】Envi插件大全:多波段拆分工具的巧妙使用

很多场合下需要做波段合成,比如波段432合成赋予红绿蓝,构造标准假彩色等等。合成后的文件通常包含多个单波段文件,在Envi中使用layer stacking工具将多个单波段数据合成为一个文件,如下所示: 那么问题来了,合成后的数据该怎样拆开为原来的单波段呢?今天我们就来学习一种…

php表格怎么合并单元格格式化,table标签的结构与合并单元格的实现方法

1.示例代码&#xff1a;复制代码 代码如下:#1234一个完整的例子&#xff1a;复制代码 代码如下:#FirstnameLastnamePhoneQQ1qianshou111111111111111111112qianshou111111111111111111113qianshou111111111111111111114qianshou111111111111111111112.合并上下的单元格(rowspan…

《看聊天记录都学不会C语言?太菜了吧》(9)老公饼真的有老公送?

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖…

@Springboot搭建项目controller层接收json格式的对象失败

今天在使用swagger2测试的时候出错 1、requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容&#xff0c;比如说&#xff1a;application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。 2、 通过req…

『技术群里聊些啥』HttpClient 如何判断是同一终结点

前言官方文档对 HttpClientHandler.MaxConnectionsPerServer 属性有如下说明&#xff1a;获取或设置使用 HttpClient 对象发出请求时允许的最大并发连接数&#xff08;每个服务器终结点&#xff09;。请注意&#xff0c;该限制针对每个服务器终结点&#xff0c;例如&#xff0c…

【Envi风暴】Envi 5.3 SP1经典安装手把手图文教程(含补丁文件)

Envi 5.3具有传感器和数据支持、图像处理和显示、用户界面、二次开发等新功能,本文讲解Envi 5.3 SP1完全安装教程。 下载后的软件包目录如下所示: 目录 一、Envi 5.3 SP1安装 二、Envi 5.3 SP1下载地址 一、Envi 5.3 SP1安装 点击IDL_ENVI5.3 SP1win64.exe,开始安装,…

《看聊天记录都学不会C语言?太菜了吧》(10)程序媛聪明绝顶了

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖…

遥感方法研究张掖市1999-2010年土地利用变化

【方法思路】:本文选取张掖地区两期影像(Landsat 1999-07-07,2010-09-07),用监督分类方法获取各期土地利用类型,与已有的土地利用现状矢量图(landuse2000)相叠加,通过对比分析,进而得出张掖市1999-2010年间土地利用变化情况。 一、实验数据 采用Landsat Tm影像,原始…

【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象

在实际更新Mongo对象时发现&#xff0c;原有的更新代码无法更新复杂的数据类型对象。恰好看到张占岭老师有对该方法做相关的改进&#xff0c;因此全抄了下来。 总的核心思想就是运用反射与递归&#xff0c;对对象属性一层一层挖掘下去&#xff0c;循环创建父类及之类的更新表达…

java openxml 操作 word,openxml word转成xml

word2007无法打开Office Open XML 文档由于种种原因&#xff0c;如程序安装错误、注册表被修改&#xff0c;或系统被病毒侵害等。有时候会造成WORD 2007无法打开.DOC文档的问题&#xff0c;常规的处理办法(右键选择“打开方式”)无效。可以试试如下的方法 &#xff1a;1.打开注…

聊一聊CLR源码中的 #define 是怎么玩的

一&#xff1a;背景 如果大家看过 CLR 源码&#xff0c;会发现里面有很多 #define 宏定义,比如说 fusionhelpers.hpp 头文件里。如果你不熟悉 C &#xff0c;看到这些 #define 应该会很晕的&#xff0c;这篇我们就来简单聊聊 define 的玩法&#xff0c;其实说白了很简单, #defi…

《看聊天记录都学不会C语言?太菜了吧》(11)2分钟领悟数组

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖…

基于CentOS 7配置Nginx正向代理

Nginx是一款以轻量级、低内存开销、支持缓存、支持反向代理&#xff0c;负载均衡&#xff0c;电子邮件服务而著称。对于鲜为人知的是&#xff0c;它还可以作为一个简单易用的正向代理服务器。本文简要描述这个正向代理功能并给出演示&#xff0c;供大家参考。 有关Nginx的安装请…

【ArcObject开发】实验:ArcObject地图开发基本操作

ArcObjects,是基于Microsoft COM技术所构建的一系列COM组件集,是在ArcGIS Desktop平台基础上的二次开发,开发语言为VBA(Vistal Basic for Application)。下面将AO开发的中的一系统基本操作做一简单的说明。 下图是功能主面板,有三个主要功能:地图漫游、地图制图和创建元素…

[Python MoviePy 音视频开发零基础到实战] 一、用6条代码为你的视频裁剪以及添加水印

一、MoviePy 安装及配置 在 Python 有一个音视频开发模块 MoviePy&#xff0c;MoviePy 依赖于 FFmepg&#xff0c;使用 MoviePy 可以对音视频进行编辑&#xff1b;例如视频合成、视频处理、视频特效等。 在 Python 下直接使用 pip 工具进行安装即可&#xff1a; pip install…

C# 使用ILogger接口编写日志

.NET 有几种不同的日志记录和跟踪工具&#xff0c;还有许多不同的第三方日志记录程序。尝试将一个应用程序从一种日志记录技术更改为另一种日志记录技术不是一件容易的事情&#xff0c;因为日志记录 API 的使用分布在整个源代码中。要使日志记录独立于任何日志记录技术&#xf…

html页面调用php常量,js中的常量变量以及html文档三种引入js的方式

js 是基于事件驱动的异步单线程的脚本编程语言&#xff0c;它的全称是 JavaScript&#xff0c;虽然里边有个 java 字样&#xff0c;但是和 java 编程语言一点关系都没有。它是一种脚本语言&#xff0c;基于解释器执行&#xff0c;它是边解释便执行的语言。浏览器控制台 Console…

【ArcGIS风暴】基于ArcGIS空间分析功能研究渭河流域镇驻地空间分布格局

【内容提要】:基于ArcGIS平台,借助空间分析的方法,用空间平滑法(基于移动搜索法FAC和核估计)分析渭河流域镇驻地的分布特征。 实验过程 1. 加载数据 渭河流域的居民点(Resident_point.shp),DEM(等高线)、水系(线)、道路(线)空间数据,如下图所示。