【EF Core】Entity Framework Core 批处理语句
在Entity Framework Core (EF Core)有许多新的功能,最令人期待的功能之一就是批处理语句。那么批处理语句是什么呢?批处理语句意味着它不会为每个插入/更新/删除语句发送单独的请求,它将在数据库的单次请求中批量执行多个语句。在这篇文章中,让我们看看它是如何工作的,并将结果与EF6进行比较。
EF Core将一次准备多个语句,然后在单次请求中执行它们,所以能提供了更好的性能和速度。让我们看看它是如何工作的。我们将借助SQL Server Profiler来捕获实际生成和执行的查询。
插入操作
首先,我们来看看插入语句的行为,以下代码在category表中添加3个记录:
using (var dataContext = new SampleDBContext()) {
dataContext.Categories.Add(new Category() {
CategoryID = 1,
CategoryName = "Clothing"
});
dataContext.Categories.Add(new Category() {
CategoryID = 2,
CategoryName = "Footwear"
});
dataContext.Categories.Add(new Category() {
CategoryID = 3,
CategoryName = "Accessories"
});
dataContext.SaveChanges();
}
当执行SaveChanges()时,以下是生成语句(通过 SQL Server Profiler 捕获):
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [Categories] ([CategoryID], [CategoryName])
VALUES (@p0, @p1),
(@p2, @p3),
(@p4, @p5);
',N'@p0 int,@p1 nvarchar(4000),@p2 int,@p3 nvarchar(4000),@p4 int,@p5 nvarchar(4000)',@p0=1,@p1=N'Clothing',@p2=2,@p3=N'Footwear',@p4=3,@p5=N'Accessories'
您可以看到,没有3条单独的插入语句,它们被组合成一个语句,并且使用表值参数作为值。这里是SQL Server Profiler的屏幕截图:

如果我们在EF 6执行相同的代码,那么在SQL Server Profiler中会看到3个单独的插入语句:

这在性能和速度方面有很大的不同。如果这些查询针对的是云部署的数据库,那么它也将具有更高成本效益。现在,我们看看如果是更新语句会发生什么。
更新操作
以下代码将获得所有category记录列表,然后遍历它们,并为每个类别名称追加“-Test”文本,并保存。在这个时间点上,数据库中只有3条记录。
using (var dataContext = new SampleDBContext()) {
List<Category> lst = dataContext.Categories.ToList();
foreach (var item in lst) {
item.CategoryName = item.CategoryName + "-Test";
}
dataContext.SaveChanges();
}
并且在EF Core执行时,生成以下查询(通过 SQL Server Profiler 捕获)。
exec sp_executesql N'SET NOCOUNT ON;
UPDATE [Categories] SET [CategoryName] = @p0
WHERE [CategoryID] = @p1;
SELECT @@ROWCOUNT;
UPDATE [Categories] SET [CategoryName] = @p2
WHERE [CategoryID] = @p3;
SELECT @@ROWCOUNT;
UPDATE [Categories] SET [CategoryName] = @p4
WHERE [CategoryID] = @p5;
SELECT @@ROWCOUNT;
',N'@p1 int,@p0 nvarchar(4000),@p3 int,@p2 nvarchar(4000),@p5 int,@p4 nvarchar(4000)',@p1=1,@p0=N'Clothing-Test',@p3=2,@p2=N'Footwear-Test',@p5=3,@p4=N'Accessories-Test'
您可以看到,有3个更新语句,但都被组合成单条SQL语句。在EF 6执行相同的代码,SQL Server Profiler中将显示3个单独的更新语句:

使用EF 6,将有1 + N往返数据库,一次加载数据以及每行数据的修改;但是使用EF Core,保存操作是批量的,所以只有两次往返数据库。
插入、更新、删除混合操作
现在让我们尝试将3个操作混合在一起,看看EF Core和EF 6的行为。以下代码将更新现有记录,并插入2条新记录,最后删除一条记录。
using (var dataContext = new SampleDBContext())
{
Category cat = dataContext.Categories.First(c => c.CategoryID == 3);
cat.CategoryName = "Accessory";
dataContext.Categories.Add(new Category() { CategoryID = 4, CategoryName = "Fragnance" });
dataContext.Categories.Add(new Category() { CategoryID = 5, CategoryName = "Sports" });
Category catToDelete = dataContext.Categories.First(c => c.CategoryID == 2);
dataContext.Entry(catToDelete).State = EntityState.Deleted;
dataContext.SaveChanges();
}
当执行SaveChanges()时,生成以下查询(通过 SQL Server Profiler 捕获):
exec sp_executesql N'SET NOCOUNT ON;
DELETE FROM [Categories]
WHERE [CategoryID] = @p0;
SELECT @@ROWCOUNT;
UPDATE [Categories] SET [CategoryName] = @p1
WHERE [CategoryID] = @p2;
SELECT @@ROWCOUNT;
INSERT INTO [Categories] ([CategoryID], [CategoryName])
VALUES (@p3, @p4),
(@p5, @p6);
',N'@p0 int,@p2 int,@p1 nvarchar(4000),@p3 int,@p4 nvarchar(4000),@p5 int,@p6 nvarchar(4000)',@p0=2,@p2=3,@p1=N'Accessory',@p3=4,@p4=N'Fragnance',@p5=5,@p6=N'Sports'
正如您所看到的,有单个DELETE,UPDATE和INSERT语句,但被组合成一个单独的SQL语句。这里是SQL Server Profiler的屏幕截图:

在EF 6的中会发生什么?嗯,您猜对了。您可以通过 SQL Profiler 看到在数据库上执行的单个语句:

因此,使用EF Core进行批处理可以很大程度提高应用程序的速度和性能。等等,如果大型查询(如要插入500列和100行的表)会发生什么?它会失败吗?
批处理限制取决于您的数据库提供者。例如,SQL Server查询支持的参数最大数量为2100,因此,EF Core在此范围内可以漂亮地工作,并且当批处理限制超出数据库提供程序范围时,将分批查询。但是,在一个查询中批处理所有内容有时不一定是个好方式。有没有办法禁用批处理?
如何禁用批处理
是的,您可以禁用批处理。要禁用批处理,需要修改MaxBatchSize选项,您可以在OnConfiguring方法中进行配置。
protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
{
string sConnString = @"Server=localhost;Database=EFSampleDB;Trusted_Connection=true;";
optionbuilder.UseSqlServer(sConnString , b => b.MaxBatchSize(1));
}
这里,将最大批量大小设置为1,这意味着批处理现在只能是单条查询。换句话说,它的行为类似于EF 6,要插入3个记录,将有3个单独的插入语句。使用此选项可以定义最大批量大小。
总结
批处理是期待已久的功能,并且社区也多次提出,现在EF Core已经支持,确实很棒,它可以提高应用程序的性能和速度。现在,EF Core本身还不像EF 6那么强大,但随着时间的推移,它将会越来越成熟。
原文:《What is Batching of Statement in Entity Framework Core?》http://www.talkingdotnet.com/what-is-batching-of-statement-in-entity-framework-core/
翻译:Sweet Tang
本文地址:http://www.cnblogs.com/tdfblog/p/batching-of-statement-in-entity-framework-core.html
欢迎转载,请在明显位置给出出处及链接。
【EF Core】Entity Framework Core 批处理语句的更多相关文章
- ABP 教程文档 1-1 手把手引进门之 ASP.NET Core & Entity Framework Core(官方教程翻译版 版本3.2.5)
本文是ABP官方文档翻译版,翻译基于 3.2.5 版本 官方文档分四部分 一. 教程文档 二.ABP 框架 三.zero 模块 四.其他(中文翻译资源) 本篇是第一部分的第一篇. 第一部分分三篇 1- ...
- NET Core & Entity Framework Core
ABP 教程文档 1-1 手把手引进门之 ASP.NET Core & Entity Framework Core(官方教程翻译版 版本3.2.5) 本文是ABP官方文档翻译版,翻译基于 ...
- 【EF】Entity Framework Core 软删除与查询过滤器
本文翻译自<Entity Framework Core: Soft Delete using Query Filters>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意 ...
- 【EF】Entity Framework Core 2.0 特性介绍和使用指南
阅读目录 前言 获取和使用 新特性 项目升级和核心API变化 下一步计划 遗憾的地方 回到目录 前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升 ...
- 【EF】Entity Framework Core 命名约定
本文翻译自<Entity Framework Core: Naming Convention>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意:我使用的是 Entity ...
- ASP.NET Core 入门教程 8、ASP.NET Core + Entity Framework Core 数据访问入门
一.前言 1.本教程主要内容 ASP.NET Core MVC 集成 EF Core 介绍&操作步骤 ASP.NET Core MVC 使用 EF Core + Linq to Entity ...
- ASP.NET Core 入门笔记9,ASP.NET Core + Entity Framework Core 数据访问入门
一.前言 1.本教程主要内容 ASP.NET Core MVC 集成 EF Core 介绍&操作步骤 ASP.NET Core MVC 使用 EF Core + Linq to Entity ...
- 尝试.Net Core—使用.Net Core + Entity FrameWork Core构建WebAPI(一)
想尝试.Net Core很久了,一直没有时间,今天回家,抛开一切,先搭建一个.Net Core的Demo出来玩玩. 废话少说,咱直奔主题: 一.开发环境 VS2015 Update3 Microsof ...
- .net core Entity Framework Core Code First 框架 分层开发
由于之前苦于无法把 Entityframework 跟Web层剥离.找了很久..找到了这个框架..分享给大家.. GitHub 地址:https://github.com/chsakell/dotn ...
- asp.net core + entity framework core 多数据库类型支持实战
根据微软官方文档的说法,有两种方法可以实现在一个app中同时适应多种不同类型的数据库,并且全部支持migrations操作.其一,使用两个dbcontext:其二,修改migration文件,添加特定 ...
随机推荐
- Java设计模式(4)——创建型模式之单例模式(Singleton)
一.概述 弥补一下之前没有给设计模式下的定义,先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计 ...
- IDEA阿里Java规范插件的安装
本文参考自阿飞博客:http://www.cnblogs.com/aflyun/p/7668306.html 官方使用教程:https://zhuanlan.zhihu.com/p/30191998? ...
- java.lang.RuntimeException: HRegionServer Aborted
java.lang.RuntimeException: HRegionServer Aborted 当我们启动hbase集群的时候,刚启动时每个节点上的进程都显示正常,过一会其他两个节点上的HRegi ...
- Myeclipse - 问题集 - specified vm install not found
In Eclipse, click the ant file -- Run As -- External Tools Configuration and click on the JRE tab. S ...
- 跨平台编译Go程序(交叉编译)
作用:比如你手头只有Mac系统,而你的用户有Linux和Windows的,他们也想用,你可以通过交叉编译出Linux和Windows上的可执行文件给他们用 (1)首先进入go/src 源码所在目录,执 ...
- `Facebook.Unity.Settings' has already been imported error solution
after import facebook sdk to unity, i get the '`Facebook.Unity.Settings' has already been imported' ...
- 基于阿里云服务器Linux系统安装配置Redis
一.Redis简介 Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(有 ...
- JMeter常用元器件
测试计划, 是整个工程的根节点, 可以取别名, 并添加注释, 里面的设置是全局变量: 线程组, 是一组线程的集合, 可以取别名, 并添加注释, 里面的设置只对本线程组有效: HTTP请求, 也就是取样 ...
- a链接传参的方法
//获取分案编号 var hrefVal=window.location.href.split("?")[1]; //得到id=楼主 //console.log(hrefVal+& ...
- idea clion编译器
RNMV64P0LA-eyJsaWNlbnNlSWQiOiJSTk1WNjRQMExBIiwibGljZW5zZWVOYW1lIjoiY24gdHUiLCJhc3NpZ25lZU5hbWUiOiIiL ...