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 ...
- Solr查询query效果对比
q条件 默认分词(org.apache.solr.analysis.TokenizerChain) "parsedquery" IK分词(org.wltea.analyzer.lu ...
- Linux TCP不同状态的连接数统计
方法一:利用netstat命令 统计 TIME_WAIT/CLOSE_WAIT/ESTABLISHED/LISTEN 等TCP状态的连接数 netstat -tan |grep ^tcp |awk ' ...
- JQuery中checkbox选择器
今天我们讲的是如何选择HTML网页中CheckBox选择器 如下图,是几个checkbox <input type='checkbox'checked="checked"/& ...
- .net读写xml
XML文件 <?xml version="1.0" encoding="utf-8"?> <book> <title>web ...
- C#多边形求角——实例说
前段时间有写过一个计算多边形角度的代码,这里给它整理整理,留给自己也送给萌新. 看左下图,这是一个多环的多边形,一个外环(内部为多边形内部区域),一个内环(外部为多边形内部区域),同时多边形中任意一个 ...
- WPF:MVVM模式下ViewModel关闭View
不外乎两种基本方法. 消息通知和参数传递. 一.消息通知 利用View里的IsEnable属性 原理是这样的: 1.UI中的IsEnabled绑定VM中的属性 2.UI的后台代码中,注册IsEnabl ...
- 原生 javaScript 百叶窗 效果的实现及原理介绍
百叶窗大家都见过吧!如图: 原理: 如图所示,空心格子就好比是每个li,给它设定相对定位属性,设置overflow:hidden: 黑块为li子元素,高度为li的2倍,设置absolute属性,我们正 ...
- iOS Objective-C 中 bool 与 BOOL 的你不一定知道的事
测试一下这段代码: - (void)test { NSLog(@"this is an attribut: %d", anAttribute); ; i < ; i++) { ...
- django rest framework 向数据库中插入数据时处理外键的方法
一.models.py中 from django.db import models class UserModel(models.Model) user_name = models.CharField ...