EF CORE 7 中的新功能:使用 ExecuteDelete 和 ExecuteUpdate 进行批量操作

原文链接:https://timdeschryver.dev/blog/new-in-entity-framework-7-bulk-operations-with-executedelete-and-executeupdate

原文作者:tim_deschryver

翻译:沙漠尽头的狼(谷歌翻译加持)

Entity Framework 7 包括一些已被要求的流行功能,其中之一是批量操作。Julie Lerman 的一条推文[1]引起了我的注意,我不得不亲自尝试一下。

推文地址:https://twitter.com/julielerman/status/1557743067691569156[2]

07ffb0f03b8dec1af9a74534f95966ea.png
https://twitter.com/julielerman/status/1557743067691569156

为什么?

那么,如果我们已经可以更新和删除实体,为什么还需要这个功能呢?这里的关键词是性能。这是一个在 EF 新版本中一直位居榜首的主题,这次也不例外。

添加的方法以多种方式提高了性能。而不是首先检索实体并将所有实体存储在内存中,然后我们才能对它们执行操作,最后将它们提交给 SQL。我们现在只需一个操作就可以做到这一点,这会产生一个 SQL 命令。

让我们看看它在代码中的样子。

设置场景

在我们深入示例之前,让我们首先配置我们的 SQL 数据库并填充 3 个表:

  • Persons: 人

  • Addresses: 地址( 一个人有一个地址)

  • Pets: 宠物(一个人可以养很多宠物)

using Microsoft.EntityFrameworkCore;using (var context = new NewInEFContext())
{SetupAndPopulate(context);
}static void SetupAndPopulate(NewInEFContext context)
{context.Database.EnsureDeleted();context.Database.EnsureCreated();context.Persons.AddRange(Enumerable.Range(1, 1_000).Select(i =>{return new Person{FirstName = $"{nameof(Person.FirstName)}-{i}",LastName = $"{nameof(Person.LastName)}-{i}",Address = new Address{Street = $"{nameof(Address.Street)}-{i}",},Pets = Enumerable.Range(1, 3).Select(i2 =>{return new Pet{Breed = $"{nameof(Pet.Breed)}-{i}-{i2}",Name = $"{nameof(Pet.Name)}-{i}-{i2}",};}).ToList()};}));context.SaveChanges();
}public class NewInEFContext : DbContext
{public DbSet<Person> Persons { get; set; }public DbSet<Pet> Pets { get; set; }public DbSet<Address> Addresses { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder options)=> options.UseSqlServer("Connectionstring");protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity<Address>().Property<long>("PersonId");modelBuilder.Entity<Pet>().Property<long>("PersonId");}
}public class Person
{public long PersonId { get; set; }public string FirstName { get; set; } = "";public string LastName { get; set; } = "";public Address? Address { get; set; }public List<Pet> Pets { get; set; } = new List<Pet>();
}public class Address
{public long AddressId { get; set; }public string Street { get; set; } = "";
}public class Pet
{public long PetId { get; set; }public string Breed { get; set; } = "";public string Name { get; set; } = "";
}

ExecuteDelete 和 ExecuteDeleteAsync

既然我们已经解决了这个问题,让我们深入研究ExecuteDeleteExecuteDeleteAsync

要批量删除一组实体,请使用Where方法过滤掉要删除的实体(与之前类似)。然后,调用ExecuteDelete方法删除实体集合。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);context.Pets.Where(p => p.Name.Contains("1")).ExecuteDelete();
}

让我们也看看它生成的 SQL 语句:

DELETE FROM [p]
FROM [Pets] AS [p]
WHERE [p].[Name] LIKE N'%1%'

如您所见,它只是生成一条 SQL 语句来删除符合条件的实体。这些实体也不再保存在内存中。不错,简单,高效!

级联删除

让我们看另一个例子,让我们删除一些持有地址和宠物引用的人。通过删除人员,我们也删除了地址和宠物,因为删除语句级联到外部表。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);context.Persons.Where(p => p.PersonId <= 500).ExecuteDelete();
}

与之前类似,这会产生以下 SQL 语句:

DELETE FROM [p]
FROM [Persons] AS [p]
WHERE [p].[PersonId] <= CAST(500 AS bigint)

受影响的行数

还可以查看删除操作影响了多少行,ExecuteDelete返回受影响的行数。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);var personsDeleted =context.Persons.Where(p => p.PersonId <= 100).ExecuteDelete();
}

在上面的表达式中,personsDeleted变量等于 100。

ExecuteUpdate 和 ExecuteUpdateAsync

现在我们已经了解了如何删除实体,让我们探索如何更新它们。就像ExecuteDelete,我们首先必须过滤我们想要更新的实体,然后调用ExecuteUpdate.

要更新实体,我们需要使用新SetProperty方法。SetProperty的第一个参数是通过 lambda 选择需要更新的属性,第二个参数也使用 lambda 选择该属性的新值,。

例如,让我们将人员的姓氏设置为“Updated”。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);context.Persons.Where(p => p.PersonId <= 1_000).ExecuteUpdate(p => p.SetProperty(x => x.LastName, x => "Updated"));
}

这会生成相应的 SQL 语句:

UPDATE [p]SET [p].[LastName] = N'Updated'
FROM [Persons] AS [p]
WHERE [p].[PersonId] <= CAST(1000 AS bigint)

我们还可以访问实体的值并使用它来创建新值。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);context.Persons.Where(p => p.PersonId <= 1_000).ExecuteUpdate(p => p.SetProperty(x => x.LastName, x => "Updated" + x.LastName));
}

产生以下 SQL 语句:

UPDATE [p]SET [p].[LastName] = N'Updated' + [p].[LastName]
FROM [Persons] AS [p]
WHERE [p].[PersonId] <= CAST(1000 AS bigint)

一次更新多个值

我们甚至可以通过多次调用SetProperty来一次更新多个属性。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);context.Persons.Where(p => p.PersonId <= 1_000).ExecuteUpdate(p =>p.SetProperty(x => x.LastName, x => "Updated" + x.LastName).SetProperty(x => x.FirstName, x => "Updated" + x.FirstName));
}

再一次,对应的 SQL 语句:

UPDATE [p]SET [p].[FirstName] = N'Updated' + [p].[FirstName],[p].[LastName] = N'Updated' + [p].[LastName]
FROM [Persons] AS [p]
WHERE [p].[PersonId] <= CAST(1000 AS bigint)

受影响的行数

就像ExecuteDelete,ExecuteUpdate也返回受影响的行数。

using (var context = new NewInEFContext())
{SetupAndPopulate(context);var personsUpdated =context.Persons.Where(p => p.PersonId <= 1_000).ExecuteUpdate(p => p.SetProperty(x => x.LastName, x => "Updated"));
}

请注意,不支持更新嵌套实体。

Entity Framework 7 中的更多更新

有关新功能的完整列表,请参阅EF 7 计划[3]

参考资料

[1]

Julie Lerman 的一条推文: https://twitter.com/julielerman

[2]

https://twitter.com/julielerman/status/1557743067691569156: https://twitter.com/julielerman/status/1557743067691569156

[3]

EF 7 计划: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/plan?WT.mc_id=DT-MVP-5004452

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

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

相关文章

java 简单json和对象相互转换

2019独角兽企业重金招聘Python工程师标准>>> package Fasterxml; import com.fasterxml.jackson.databind.ObjectMapper; import mode.User; import java.io.StringWriter; import java.util.ArrayList; import java.util.List;/*** maven...**<dependency>* …

畅想动画制作的乐趣

为什么要制作动画&#xff1f; 现在的营销活动&#xff0c;用一个很简单的图片去吸引消费者已经远远不够。想让消费者创造GMV&#xff0c;肯定需要让消费者觉得眼前一亮或是有视觉冲击的东西&#xff0c;或者在动画过程中提供更好的引导部分&#xff0c;比如红包&#xff0c;引…

Spring Cloud Gateway 原生支持接口限流该怎么玩

关于pig&#xff1a; 基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台&#xff0c;支持账号、短信、SSO等多种登录&#xff0c;提供配套视频开发教程。 关于 Spring Cloud Gateway SpringCloudGateway是Spring官方基于Spring 5.0&#xff0c;Spring Boot 2.0和Projec…

我的手机 不支持箭头函数

不支持&#xff0c;要换成function的形式 转载于:https://www.cnblogs.com/web-fusheng/p/7295901.html

中标麒麟linux卸载qt,国产化 银河麒麟编译Qt程序的问题汇总 | 阿拉灯

Run in terminal莫名奇妙软件无法在QtCreator中运行或者调试&#xff0c;main函数都无法进入&#xff0c;QtCreator中一运行就崩溃&#xff0c;并跳到汇编界面&#xff0c;这多半和代码没什么关系&#xff0c;我这里是将项目->运行中的“Run in terminal”去掉勾选&#xff…

css3-13 如何改变文本框的轮廓颜色

css3-13 如何改变文本框的轮廓颜色 一、总结 一句话总结&#xff1a;outline使用和border很像&#xff0c;几乎一模一样&#xff0c;多了一个offset属性 1、轮廓outline如何使用&#xff1f; 使用和border很像&#xff0c;几乎一模一样&#xff0c;多了一个offset属性 18 …

ios添加设备真机测试,以及Undefined symbols for architecture x86_64:''错误

问题今天坑了好久&#xff0c;然后找了各种资料 添加设备这个直接去开发者中心添加一个设备进去就好&#xff0c;具体流程百度&#xff0c;第二个问题是属于路径不对或者是静态库没有添加成功&#xff0c;项目可以看到&#xff0c;到时路径找不到&#xff0c;你把静态库拖到桌面…

Kinect2.0获取数据

最近事情真是多&#xff0c;今天抽空研究一下Kinec2.0的数据获取&#xff01; 系统要求 https://developer.microsoft.com/en-us/windows/kinect/hardware-setup 系统环境 联想Y430P&#xff0c;Windows10 首先安装了Kinect for Windows SDK &#xff08;KinectSDK-v2.0_1409-S…

linux超级工具,linux运维超级工具--sysdig

sysdig 是一个超级系统工具,它可以用来捕获系统状态信息&#xff0c;在运维工作中sysdig能很方便的排查异常、定位故障&#xff0c;它还能保存数据进行分析&#xff0c;并且提供强大的命令接口。在了解sysdig强大之处之前,首先得安装sysdig&#xff0c;我这里是环境是centos6.7…

Asp.net mvc 知多少(一)

本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan&#xff0c;想看英文原版的可访问http://www.dotnettricks.com/free-ebooks自行下载。该书主要分为两部分&#xff0c;ASP.NET MVC 5、ASP.NET WEB API2。本书最大的特点是以面试问答…

stm32h7能跑linux,STM32H7榨干了Cortex-M7的最后一滴血

原标题&#xff1a;STM32H7榨干了Cortex-M7的最后一滴血有个非常重磅的消息ST给自己的STM32家族又新增了一条新的产品线—— H7H 代表的是High Pefrmance之意 (此为笔者臆测)7 则表示这是基于ARM Cortex-M7架构修改而来熟悉的工程师可能会问&#xff0c;不是已经有基于M7架构的…

通过PowerShell进行网络分析

好久没有写文章&#xff0c;因为确实工作也比较忙。今天周末&#xff0c;稍微有些时间&#xff0c;在解决一个问题时&#xff0c;用到了一点抓取和处理网络数据的小技巧&#xff0c;摘录分享如下。问题描述我有一个需求&#xff0c;就是要研究某个网页加载过程中具体发起了多少…

c语言不规则窗口,C语言不规则数组和指针

不规则数组是每一行的列数不一样的二维数组&#xff0c;其原理如下图所示&#xff0c;图中的数组有3行&#xff0c;每行有不同的列数。在了解如何创建不规则数组之前&#xff0c;让我们先看一下用复合字面量创建的二维数组。复合字面量是一种C构造&#xff0c;前面看起来像类型…

php spl_autoload_register() 函数

spl_autoload_register()的用法&#xff1a; 其中$this表示当前类&#xff0c;autoload()是我注册的自动加载函数&#xff0c;当然这个只是一个函数名&#xff0c;只要不与php的关键字重复&#xff0c;符合一般函数名的命名规范即可。 使用自动加载之后&#xff0c;当我们在一个…

C语言中递归什么时候能够省略return引发的思考:通过内联汇编解读C语言函数return的本质...

C语言中递归什么时候能够省略return引发的思考&#xff1a;通过内联汇编解读C语言函数return的本质 事情的经过是这种&#xff0c;博主在用C写一个简单的业务时使用递归&#xff0c;因为粗心而忘了写return。结果发现返回的结果依旧是正确的。经过半小时的反汇编调试。证明了我…

C# 为什么说CM+Fody+HC是WPF开发的最强组合?

01—名词解析CM&#xff1a;Caliburn.Micro(简称CM)一经推出便备受推崇&#xff0c;作为一款MVVM开发模式的经典框架&#xff0c;越来越多的受到wpf开发者的青睐.我们看一下官方的描述&#xff1a;Caliburn是一个为Xaml平台设计的小型但功能强大的框架。Micro实现了各种UI模式&…

c语言逻辑运算符两侧运算对象,逻辑运算符两侧运算对象的数据类型是什么?...

逻辑运算符两侧运算对象的数据类型&#xff1a;可以是任何合法的类型数据&#xff1b;因为逻辑运算符两边的运算对象&#xff0c;最终都被转换成bool值(逻辑值)操作。0、null转换为false&#xff0c;而所有非零、非false、非null值转换为true&#xff1b;然后进行运算。逻辑运算…

创建相似对象,就交给『工厂模式』吧

源码&#xff1a; 源代码C# 系列导航&#xff1a; 目录 定义&#xff08;Factory Pattern&#xff09;&#xff1a; 用来创建目标对象的类&#xff0c;将相似对象的创建工作统一到一个类来完成。 一、简单工厂模式&#xff1a; 代码&#xff1a; /// <summary>/// 产品枚…

《ASP.NET Core 6框架揭秘》实例演示[26]:跟踪应用接收的每一次请求

很多人可能对ASP.NET Core框架自身记录的诊断日志并不关心&#xff0c;其实这些日志对纠错排错和性能监控提供了很有用的信息。如果需要创建一个APM&#xff08;Application Performance Management&#xff09;系统来监控ASP.NET Core应用处理请求的性能及出现的异常&#xff…

阿里云Maven镜像配置

2019独角兽企业重金招聘Python工程师标准>>> <mirror><id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> …