在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'

正如您所看到的,有单个DELETEUPDATEINSERT语句,但被组合成一个单独的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

欢迎转载,请在明显位置给出出处及链接。

Entity Framework Core 批处理语句的更多相关文章

  1. 【EF Core】Entity Framework Core 批处理语句

    在Entity Framework Core (EF Core)有许多新的功能,最令人期待的功能之一就是批处理语句.那么批处理语句是什么呢?批处理语句意味着它不会为每个插入/更新/删除语句发送单独的请 ...

  2. Entity Framework Core 执行SQL语句和存储过程

    无论ORM有多么强大,总会出现一些特殊的情况,它无法满足我们的要求.在这篇文章中,我们介绍几种执行SQL的方法. 表结构 在具体内容开始之前,我们先简单说明一下要使用的表结构. public clas ...

  3. EF Core 批处理语句

    在Entity Framework Core (EF Core)有许多新的功能,最令人期待的功能之一就是批处理语句.那么批处理语句是什么呢?批处理语句意味着它不会为每个插入/更新/删除语句发送单独的请 ...

  4. 全自动迁移数据库的实现 (Fluent NHibernate, Entity Framework Core)

    在开发涉及到数据库的程序时,常会遇到一开始设计的结构不能满足需求需要再添加新字段或新表的情况,这时就需要进行数据库迁移. 实现数据库迁移有很多种办法,从手动管理各个版本的ddl脚本,到实现自己的mig ...

  5. Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 读取关系数据

    Reading related data¶ 9 of 9 people found this helpful The Contoso University sample web application ...

  6. Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 创建复杂数据模型

    Creating a complex data model 创建复杂数据模型 8 of 9 people found this helpful The Contoso University sampl ...

  7. Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 排序、筛选、分页以及分组

    Sorting, filtering, paging, and grouping 7 of 8 people found this helpful By Tom Dykstra The Contoso ...

  8. Entity Framework Core 软删除与查询过滤器

    本文翻译自<Entity Framework Core: Soft Delete using Query Filters>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意 ...

  9. .Net Core 2.0生态(4):Entity Framework Core 2.0 特性介绍和使用指南

    前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升级EF也发展到EF6.x,Entity Framework Core是一个支持跨平台的全新版本, ...

随机推荐

  1. OWIN的概念初接触

    OWIN这个词我昨天才认识,一直疑惑它是个什么东西,通过一定量的研究,得到一个初步的认识,留个脚印. OWIN是什么 OWIN是一个规范和标准,旨在阐述web服务器和web应用应该如何去解耦,它使得原 ...

  2. 可视化之Earth NullSchool

    上两篇我们分别介绍了<Berkeley Earth>和<AQICN>两个网站,今天来看一下Earth NullSchool. 这个网站的特色是风向图,之前有一篇可视化之风向图, ...

  3. if 一元二次方程求根

    if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码 if...else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码 if...else if... ...

  4. 浅尝JavaScript document对象

    document对象 每个载入浏览器的 HTML 文档都会成为 Document 对象.document 对象是HTML文档的根节点与所有其他节点(元素节点,文本节点,属性节点, 注释节点).Docu ...

  5. ViewPager实现无限轮播踩坑记

    最近笔者想通过ViewPager来实现一个广告Banner,并实现无限轮播的效果,但是在这个过程中踩了不少的坑,听我慢慢道来.如果大家有遇到和我一样的情况,可以参考我的解决方法,没有那就更好,如果针对 ...

  6. 通过 itms:services://? 在线安装ipa ,跨过app-store

    1.需要一个html文件,引导下载用户在线安装ipa <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN&quo ...

  7. 你不知道的 flex 技巧

    一.使用 Auto Margins 对齐 不需要给图片使用任何的 flex,也不需要给父容器设置 space-between,只需要给 ' BUY-BUY-BUY' 按钮设置 margin-left: ...

  8. 【2017年最新】iOS面试题及答案

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 20.0px "PingFang SC Semibold"; color: #46464 ...

  9. 打造一个简单的Java字节码反编译器

    简介 本文示范了一种反编译Java字节码的方法,首先通过解析class文件,然后将解析的结果转成java代码.但是本文并没有覆盖所有的class文件的特性和指令,只针对部分规范进行解析. 所有的代码代 ...

  10. webpackage 2.x 使用

    webpackage 2.x 使用 安装---(在项目目录下) //1.初始化npm的配置(添加package.json) npm init //2.安装 webpackage npm install ...