原文链接: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]

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

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

  1. spring 5.x(1)-----Spring Framework 5.x中的新功能

    Spring Framework 5.x中有什么新功能 5.1版中的新功能 一般核心修订 基础设施: 在类路径和模块路径上对JDK 11的无警告支持. 支持Graal原生图像约束(反射,参数名称). ...

  2. bit1618c 功能简介_c 9中的新功能简介

    bit1618c 功能简介 With the upcoming release of .NET 5 - the release which unifies the .NET runtimes - Mi ...

  3. drx功能开启后_简单实用!小米手机中这些新功能真香

    小米手机作为国产机热销品牌之一,它除了有好看的外观,还有很多隐藏的实用功能,今天小编就来和大家分享5个小米手机里你不知道的功能. Al电话助理 看到陌生号码时,很多人第一反应就是挂掉,不想接听,但又担 ...

  4. SQLSERVER2014中的新功能

    SQLSERVER2014中的新功能 转载自:http://blog.csdn.net/maco_wang/article/details/22701087 博客人物:maco_wang SQLSER ...

  5. java中怎样定义实数_Java Math 类中的新功能,第 1 部分: 实数

    在这篇由两部分组成的文章中,Elliotte Rusty Harold 与您一起探讨经典 java.lang.Math 类中的"新"功能.第 1 部分主要讨论比较单调的数学函数.第 ...

  6. Windows Server 2012 DHCP 服务器中的新功能:故障转移和策略

    Windows Server 2012 DHCP 服务器中的新功能如下: DHCP 故障转移:此功能提供让两个 DHCP 服务器服务于 同一子网或作用域的 IP 地址和选项配置的能力,前提是 DHCP ...

  7. 浅析 EF Core 5 中的 DbContextFactory

    EF Core 5 中的 DbContextFactory Intro 使用过 EF Core 大多都会遇到这样一个场景,希望能够并行查询,但是如果使用同一个 DbContext 实例进行并行操作的时 ...

  8. Java平台,标准版Oracle JDK 9中的新功能

    Java平台,标准版 Oracle JDK 9中的新增功能 版本9 E77563-05 2017年9月 JDK 9中的新功能概述 Java Platform,Standard Edition 9是一个 ...

  9. Java 11中的新功能和API详解系列1

    Java 11中的新功能和API详解系列1 2018.9.27 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. JDK 11在语言语法方面有一个小改动,增加了相当数量的新API,以及 ...

最新文章

  1. loadruner中加中Java_Script
  2. [官版翻译]OpenStack centos版安装(三)
  3. 水泵怎么做_不是说鱼缸里放置三合一水泵都会起到反作用,也得看什么缸什么鱼...
  4. PHP 5.5.38 + mysql 5.0.11 + zabbix3.0 + nginx 安装
  5. nginx-启动gzip、虚拟主机、请求转发、负载均衡
  6. pythontxt文件怎么读_python怎么读txt文件
  7. 在线机器学习FTRL(Follow-the-regularized-Leader)算法介绍
  8. 贷款机构如何审核个人征信?
  9. java中实现客户姓名添加和显示
  10. 汇编 align_从零开始自制操作系统(5):实模式汇编(二)
  11. I/O、Applet以及其他主题
  12. 使用Docker 安装jdk8
  13. 有限元方法数学理论之分片一次多项式空间逼近理论
  14. 微型计算机延时,延迟时间
  15. ios appstore 审核 Guideline 5.2.2 - Legal ios新闻资讯类APP5.2.2被拒
  16. html常用长度单位
  17. k8spod控制器概述
  18. Hash 表详解(哈希表)
  19. 在服务器系统Windows 2003安装Avira AntiVir小红伞免费个人版
  20. Unity2D游戏学习

热门文章

  1. foc 电流环解耦_车用永磁同步电动机电流环偏差解耦控制系统
  2. sftp乱码处理问题
  3. 微粒贷正确使用方法解析,认准官方入口不迷路
  4. java关键字abstract(抽象)详解
  5. Shiro 与 Spring框架整合基本配制说明
  6. 智能语音AI机器人部署中的战斗机
  7. 阿里直播平台面临的技术挑战
  8. k8s 驱逐 磁盘空间不足
  9. 敏捷如何应对变化:敏捷团队检查和适应
  10. 清华大学视频课件:基于Linux的C++