AutoDetectChangesEnabled及AddRange解决EF插入的性能问题
转自:http://www.cnblogs.com/nianming/archive/2013/06/07/3123103.html#2699851
记录下。
园友莱布尼茨写了一篇《Entity Framework数据插入性能追踪》的文章,我感觉不错,至少他提出了问题,写了出来,引起了大家的讨论,这就是一个氛围。读完文章+评论,于是我自己也写了个简单的程序试了试。
先晒一下代码:
两个简单的类:
: /// <summary>
: /// 消费者
: /// </summary>
: public class Consumer
: {
: public int CId { get; set; }
: public string CName { get; set; }
: public List<Order> Orders { get; set; }
: }
:
: /// <summary>
: /// 订单
: /// </summary>
: public class Order
: {
: public int OrderNo { get; set; }
: public DateTime OrderDate { get; set; }
: public decimal TotalMoney { get; set; }
: public int CId { get; set; }
:
: public Consumer Consumer { get; set; }
: } 映射配置: : public class ConsumerConfiguration : EntityTypeConfiguration<Consumer>
: {
: public ConsumerConfiguration()
: {
: HasKey(t => t.CId).Property(t => t.CId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
: Property(t => t.CName).IsRequired().HasMaxLength();
: }
: }
:
: public class OrderConfiguration : EntityTypeConfiguration<Order>
: {
: public OrderConfiguration()
: {
: HasKey(t => t.OrderNo);
: HasRequired(t => t.Consumer).WithMany(t => t.Orders).HasForeignKey(t => t.CId);
: }
: }
Context: : public class TestContext : DbContext
: {
: public DbSet<Consumer> Consumers { get; set; }
: public DbSet<Order> Orders { get; set; }
:
: protected override void OnModelCreating(DbModelBuilder modelBuilder)
: {
: modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
:
: modelBuilder.Configurations.Add(new ConsumerConfiguration());
: modelBuilder.Configurations.Add(new OrderConfiguration());
:
: base.OnModelCreating(modelBuilder);
: }
: }
测试代码: : static void Main(string[] args)
: {
: using (var ctx = new TestContext())
: {
: ctx.Consumers.Add(new Consumer()
: {
: CName = "张三"
: });
: ctx.SaveChanges();
:
: Stopwatch sw = new Stopwatch();
: sw.Start();
: Console.WriteLine("订单开始:\n");
:
: for (int outer = ; outer < ; outer++)
: {
: ctx.Orders.Add(new Order()
: {
: OrderDate = DateTime.Now,
: TotalMoney = ,
: CId = ,
: });
: }
: ctx.SaveChanges();
: sw.Stop();
: Console.WriteLine(sw.Elapsed.Minutes + "分" + sw.Elapsed.Seconds + "秒" + sw.Elapsed.Milliseconds + "毫秒");
: }
: }
上面的代码是最平常的代码了,没有什么可解释的,将内容放到重点上。
运行以上代码的环境是VS2012+SQL SERVER 2008 R2,机器配置:4G,N年以前的CPU。
运行上面的代码非常的慢,正如莱布尼茨说的,在数据Add到上下文这个阶段比较耗时。出现这个问题的原因是:每次调用ctx.Orders.Add(order)之前,EF都会调用DetectChanges,在StackOverFlow上有解释,地址是:http://stackoverflow.com/questions/9439430/improving-performance-of-initializing-dbset-in-seed,另外在Programming Entity Framework DbContext这本书的60也有DetectChange的介绍。
解决上面速度慢的问题的办法就是设置
1: ctx.Configuration.AutoDetectChangesEnabled = false;
下面来看看禁用以后的执行速度:
另外一个解决办法就是使用DbSet<T>.AddRange方法,这个方法是在6.0 beta1中加入的。
: List<Order> orderList = new List<Order>();
: for (int outer = ; outer < ; outer++)
: {
: orderList.Add(new Order()
: {
: OrderDate = DateTime.Now,
: TotalMoney = ,
: CId =
: });
: }
: ctx.Orders.AddRange(orderList);
: ctx.SaveChanges();
AddRange方法在System.Data.Entity 泛型DbSet类中,下图是我通过Reflector截的图
从上面两幅图中可以看到,Add和AddRange都是添加到_internalSet中,但是如果AutoDetectChangesEnabled设置为true的话,添加任何实体之前都会调用DetectChanges,注意看Remarks中的解释。
AutoDetectChangesEnabled及AddRange解决EF插入的性能问题的更多相关文章
- 【测试记录】EF插入查询性能
介绍 背景什么就不提了,无外乎出现了大数据需要处理.简单的说就是我测试了EF正常的插入以及一个优化小方式而已,然后做了查询记录.其余没有什么,写这篇只是为了记录结果方便以后数据参考吧. 代码介 ...
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题
一. 开篇说明 EF的性能问题一直以来经常被人所吐槽,究其原因在于“复杂的操作在生成SQL阶段耗时长,且执行效率不高”,但并不是没有办法解决,从EF本身举几个简单的优化例子: ①:如果仅是查询数据,并 ...
- 【EF】解决EF批量操作,Z.EntityFramework.Extensions 过期方案
方案一: 使用EntityFramework.Extended优点: 启下载量是Z.EntityFramework.Extensions的10倍+ 不会过期缺点:不能批量Insert 方案二:解决批量 ...
- 解决EF没有生成字段和表说明
找了很多资料,终于找到一篇真正能解决ef生成字段说明,注释的文章,收藏不了,于是转载 本文章为转载,原文地址 项目中使用了EF框架,使用的是Database-First方式,因为数据库已经存在,所以采 ...
- 【转】MySQL批量SQL插入各种性能优化
原文:http://mp.weixin.qq.com/s?__biz=MzA5MzY4NTQwMA==&mid=403182899&idx=1&sn=74edf28b0bd29 ...
- 通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...
原文:[原创]通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 'incorrect string value: '\xF0... 这篇blog重点在解决问题,如果你对 ...
- 仿小米便签图文混排 EditText解决尾部插入文字bug
一直想实现像小米便签那样的图文混排效果,收集网上的办法无非三种: 1.自定义布局,每张图片是一个ImageView,插入图片后插入EditText,缺点是实现复杂,不能像小米便签那样同时选中图片和文字 ...
- 解决table插入tr错位
table中用JavaScript插入隐藏(即display="none";)的tr时,别用display="block";换成display="&q ...
- MySQL插入数据性能调优
插入数据性能调优总结: 1.SQL插入语句调优 2.如果是InnoDB引擎的话,尝试开启事务,批量提交 3.调整MySQl数据库配置 参考: 百度空间 - MySQL插入数据性能调优 CSDN ...
随机推荐
- Linux Guard Service - 守护进程再次分裂子进程
当系统区内存不能再申请新进程的时候申请会失败 在512MB内存下最多分配的子进程数 3331 [root@localhost 05]# ./test5-1 50000 expect 50000 sub ...
- App与微信WebAPP
我的App与微信搞上了 小麦积分墙摘自网络 最近有很多开发者关心的一个问题是如何提升app的下载量,透过现象开本质,app下载量的终极目标还是为多少客户提供了服务,抛开下载量KPI,app真心关心的问 ...
- c#格式化字符
1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0 ...
- docker容器日志清理
1.先查看磁盘空间 df -h 2.找到容器的containerId-json.log文件,并清理(治标不治本,log迟早还会大的) 查看各个容器的log文件大小 find /var/lib/dock ...
- asp.net Frameset框架集的嵌套使用
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Frame.aspx.cs& ...
- sql数据库 大小查询
select * from sys.master_files where name='CODA_PRD_Catalog' 12416*8/1024=(m)
- IOS渠道追踪方式
本文来自网易云社区 作者:马军 IOS,安卓渠道追踪的差异 Google Play国内不可用,国内的安卓 App 分发,都是依托几十个不同的应用市场或发行渠道,如百度.360.腾讯等互联网企业以及小米 ...
- Cookie的创建与删除
Cookie 为 Web 应用程序保存用户相关信息提供了一种有用的方法.例如,当用户访问站点时,可以利用 Cookie 保存用户首选项或其他信息,这样,当用户下次再访问站点时,应用程序就可以检索以前保 ...
- Delphi XE2 编译ralease版本,无法添加UAC解决方法
我今天把一个原来是Delphi2007的工程升级到了Delphi XE2,在编译ralease版本时候,发现无法添加UAC,我觉得可能是升级的原因,随后我用XE2新建了一个工程,但是在编译raleas ...
- SpringMVC框架 SpringMVC的获取01
---恢复内容开始--- SpringMVC通过实现MVC模式,很好地将数据.业务与展现进行了分离.从MVC的角度来说,SpringMVC和Struts2非常类似,但SpringMVC采用了可插拔的组 ...