首页 > 其他分享 >EF Core 高效更新

EF Core 高效更新

时间:2024-04-03 22:00:35浏览次数:16  
标签:语句 Core 高效 往返 批处理 EF context

高效更新

本文内容
批处理
在相关情况下使用 ExecuteUpdate 和 ExecuteDelete
批处理
EF Core 通过在一次往返中自动将所有更新批处理在一起,帮助最大限度地减少往返。 考虑以下情况:

C#

复制
var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com");
blog.Url = "http://someotherblog.microsoft.com";
context.Add(new Blog { Url = "http://newblog1.microsoft.com" });
context.Add(new Blog { Url = "http://newblog2.microsoft.com" });
context.SaveChanges();
上述操作从数据库加载博客,更改其 URL,然后添加两个新博客;若要应用此更改,将两个 SQL INSERT 语句和一个 UPDATE 语句发送到数据库。 添加博客实例时,EF Core 不会逐个发送,而是在内部跟踪这些更改,并在调用 SaveChanges 时在单个往返中执行这些更改。

EF 在一次往返中批处理的语句数量取决于所使用的数据库提供程序。 例如,性能分析表明,当涉及的语句少于 4 个时,批处理对于 SQL Server 的效率通常较低。 同样,对于 SQL Server,批处理的优势在大约 40 条语句后会降低,因此 EF Core 默认在单个批处理中最多只执行 42 条语句,并在单独的往返中执行额外的语句。

用户也可以调整这些阈值以获得潜在的更高性能,但是在修改这些阈值之前要仔细地进行基准测试:

C#

复制
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True",
o => o
.MinBatchSize(1)
.MaxBatchSize(100));
}
在相关情况下使用 ExecuteUpdate 和 ExecuteDelete
假设你想给所有员工加薪。 EF Core 中对此的典型实现如下所示:

c#

复制
foreach (var employee in context.Employees)
{
employee.Salary += 1000;
}
context.SaveChanges();
虽然这是完全有效的代码,但是让我们从性能的角度来分析一下它的作用:

执行一次数据库往返,以加载所有相关员工;请注意,这会将员工的所有行数据带到客户端(即使只需要工资数据)。
EF Core 的更改跟踪在加载实体时创建快照,然后将这些快照与实例进行比较,找出哪些属性发生了更改。
通常,执行第二个数据库往返以保存所有更改(请注意,某些数据库提供程序将更改拆分为多次往返)。 尽管此批处理行为远远好于为每个更新执行往返,但 EF Core 仍会为每个员工发送 UPDATE 语句,并且数据库必须单独执行每个语句。
从 EF Core 7.0 开始,可以使用 ExecuteUpdate 和 ExecuteDelete 方法更高效地执行相同的操作:

c#

复制
context.Employees.ExecuteUpdate(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));
这会将以下 SQL 语句发送到数据库:

SQL

复制
UPDATE [Employees] SET [Salary] = [Salary] + 1000;
此 UPDATE 会在单次往返中执行整个操作,而无需加载任何实际数据或将这些数据发送到数据库,也无需使用 EF 的更改跟踪机制(这会增加额外的开销)。 有关详细信息,请参阅 ExecuteUpdate 和 ExecuteDelete。

如果使用的是尚不支持 ExecuteUpdate 和 ExecuteDelete 的较旧版本的 EF Core,或者想要执行这些方法不支持的复杂 SQL 语句,则仍可以使用 SQL 查询执行该操作:

EF Core 7.0
旧版本
c#

复制
context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");

标签:语句,Core,高效,往返,批处理,EF,context
From: https://www.cnblogs.com/zy8899/p/18113598

相关文章

  • 高效查询
    高效查询本文内容正确使用索引只投影需要的属性限制结果集大小高效分页在加载相关实体时避免笛卡尔爆炸尽可能预先加载相关实体缓冲和流式处理跟踪、非跟踪和标识解析使用SQL查询异步编程其他资源显示较少选项高效查询是一个庞大的主题,涵盖的主题就像索引、相关实......
  • 关于vue项目在使用vuex的时候,this.$store报错undefined的问题
    vue.runtime.esm.js?c320:4605[Vuewarn]:Errorinrender:"TypeError:Cannotreadpropertiesofundefined(reading'state')。这个问题的主要原因是vuex的版本高于vue的版本。如果vue使用2.XX,vuex的版本要低于4.XX."dependencies":{"axios":"^1.6......
  • Codeforces Round 937 (Div. 4) D题(无脑做法)
    D.ProductofBinaryDecimals题目:提示:首先如果该数目都是1和0组成那肯定输出yes了,还有这个数如果是二进制的乘积也可以yes现在举个例子看看121=11x1114641=11x11x11x11显然也是yes,但是要如何做呢,下面介绍无脑做法。AC代码#include<bits/stdc++.h>usingnamespace......
  • 黑客(网络安全)技术自学——高效学习
    01什么是网络安全网络安全可以基于攻击和防御视角来分类,我们经常听到的“红队”、“渗透测试”等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如Web安全技术,既有Web渗透,也有W......
  • 【教程】宝塔default.db占用空间几十g解决方法|宝塔占用磁盘空间特别大解决方法|宝塔
    目录一、前言二、排查问题三、解决方法一、前言用过宝塔创建网站,大家应该都非常熟悉,但是用随着用的时间越来越多,宝塔所占用的空间也越来越多,不停的加大数据盘都没有用,我原先买了30G够用了,随着时间一长,发现数据盘又满了,不得不又买了20个G扩容,可是过了一段时间又满了。......
  • [转]Docker部署Firefox容器,实现远程浏览器查看内网服务,如登录路由器配置页面等
    类似的镜像很多人都做过,找了一个start数比较多的jlesage/firefox,这个在github上有详细使用说明,我使用docker-compose.yml文件内容如下:version:'3'services:firefox:container_name:firefoximage:jlesage/firefoxports:-"5800:5800"volu......
  • FlinkSQL Unable to create a source for reading table 'default_catalog.default_da
    问题描述使用FlinkSql的jdbc连接器读取mysql的一张表,总是提示 Exceptioninthread"main"org.apache.flink.table.api.ValidationException:Unabletocreateasourceforreadingtable'default_catalog.default_database程序代码publicstaticvoidmai......
  • Codeforces Round 901 (Div. 2) E
    链接有些部分和常规的题目有很大的区别,所以我理解的过程产生的很大很大的障碍。我看了4天吧,这题和题解。好烦。我的第一个思路就是暴力。因为很明显,其实对于每一个二进制位,a,b,m的情况数量是很有限的,就只有8种,而相应的,c,d的对应位是由这4种位运算得到的。我先尝试对每一种情况看......
  • 【Redis】.Net Core 面试破冰
    目录1.Redis简介2.使用场景3.C#具体使用介绍(Nuget)StackExchange.RedisFreeRedisNewLife.RedisServiceStack.Redis(收费)4.Redis常用面试问题以及回答5.建议及经验分享建议Redis经验分享ShareFlow1.Redis简介Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持......
  • asp.net core 获取服务小计
    首先,定义服务:publicinterfaceIUserService{stringGetName();voidSetName(stringname);}publicclassUserService:IUserService{privatestringsss;publicstringGetName(){if(string.IsNullOrEmpty(sss))......