园友莱布尼茨写了一篇《Entity Framework数据插入性能追踪》的文章,我感觉不错,至少他提出了问题,写了出来,引起了大家的讨论,这就是一个氛围。读完文章+评论,于是我自己也写了个简单的程序试了试。

先晒一下代码:

两个简单的类:

   1:      /// <summary>
   2:      /// 消费者
   3:      /// </summary>
   4:      public class Consumer
   5:      {
   6:          public int CId { get; set; }
   7:          public string CName { get; set; }
   8:          public List<Order> Orders { get; set; }
   9:      }
  10:   
  11:      /// <summary>
  12:      /// 订单
  13:      /// </summary>
  14:      public class Order
  15:      {
  16:          public int OrderNo { get; set; }
  17:          public DateTime OrderDate { get; set; }
  18:          public decimal TotalMoney { get; set; }
  19:          public int CId { get; set; }
  20:   
  21:          public Consumer Consumer { get; set; }
  22:      }

映射配置:

   1:      public class ConsumerConfiguration : EntityTypeConfiguration<Consumer>
   2:      {
   3:          public ConsumerConfiguration()
   4:          {
   5:              HasKey(t => t.CId).Property(t => t.CId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
   6:              Property(t => t.CName).IsRequired().HasMaxLength(50);
   7:          }
   8:      }
   9:   
  10:      public class OrderConfiguration : EntityTypeConfiguration<Order>
  11:      {
  12:          public OrderConfiguration()
  13:          {
  14:              HasKey(t => t.OrderNo);
  15:              HasRequired(t => t.Consumer).WithMany(t => t.Orders).HasForeignKey(t => t.CId);
  16:          }
  17:      }

Context:

   1:      public class TestContext : DbContext
   2:      {
   3:          public DbSet<Consumer> Consumers { get; set; }
   4:          public DbSet<Order> Orders { get; set; }
   5:   
   6:          protected override void OnModelCreating(DbModelBuilder modelBuilder)
   7:          {
   8:              modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
   9:   
  10:              modelBuilder.Configurations.Add(new ConsumerConfiguration());
  11:              modelBuilder.Configurations.Add(new OrderConfiguration());
  12:   
  13:              base.OnModelCreating(modelBuilder);
  14:          }
  15:      }

测试代码:

   1:          static void Main(string[] args)
   2:          {
   3:              using (var ctx = new TestContext())
   4:              {
   5:                  ctx.Consumers.Add(new Consumer()
   6:                  {
   7:                      CName = "张三"
   8:                  });
   9:                  ctx.SaveChanges();
  10:   
  11:                  Stopwatch sw = new Stopwatch();
  12:                  sw.Start();
  13:                  Console.WriteLine("订单开始:\n");
  14:   
  15:                  for (int outer = 0; outer < 20000; outer++)
  16:                  {
  17:                      ctx.Orders.Add(new Order()
  18:                            {
  19:                                OrderDate = DateTime.Now,
  20:                                TotalMoney = 100,
  21:                                CId = 1,
  22:                            });
  23:                  }
  24:                  ctx.SaveChanges();
  25:                  sw.Stop();
  26:                  Console.WriteLine(sw.Elapsed.Minutes + "分" + sw.Elapsed.Seconds + "秒" + sw.Elapsed.Milliseconds + "毫秒");
  27:              }
  28:          }

上面的代码是最平常的代码了,没有什么可解释的,将内容放到重点上。

运行以上代码的环境是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中加入的。

   1:                  List<Order> orderList = new List<Order>();
   2:                  for (int outer = 0; outer < 20000; outer++)
   3:                  {
   4:                      orderList.Add(new Order()
   5:                             {
   6:                                 OrderDate = DateTime.Now,
   7:                                 TotalMoney = 100,
   8:                                 CId = 1
   9:                             });
  10:                  }
  11:                  ctx.Orders.AddRange(orderList);
  12:                  ctx.SaveChanges();

AddRange方法在System.Data.Entity 泛型DbSet类中,下图是我通过Reflector截的图

从上面两幅图中可以看到,Add和AddRange都是添加到_internalSet中,但是如果AutoDetectChangesEnabled设置为true的话,添加任何实体之前都会调用DetectChanges,注意看Remarks中的解释。

测试源码下载地址:http://www.ef-community.com/forum.php?mod=viewthread&tid=437&extra=page%3D1

"Entity Framework数据插入性能追踪"读后总结的更多相关文章

  1. Lazy<T>在Entity Framework中的性能优化实践

    Lazy<T>在Entity Framework中的性能优化实践(附源码) 2013-10-27 18:12 by JustRun, 328 阅读, 4 评论, 收藏, 编辑 在使用EF的 ...

  2. 大数据应用之HBase数据插入性能优化实测教程

    引言: 大家在使用HBase的过程中,总是面临性能优化的问题,本文从HBase客户端参数设置的角度,研究HBase客户端数据批量插入性能优化的问题.事实胜于雄辩,数据比理论更有说服力,基于此,作者设计 ...

  3. Entity Framework 数据并发访问错误原因分析与系统架构优化

    博客地址 http://blog.csdn.net/foxdave 本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上 ...

  4. 关于Entity Framework采用DB First模式创建后的实体批量修改相关属性技巧

    Entity Framework采用DB First模式创建实体是比较容易与方便的,修改已创建的实体在个数不多的情况下也是没问题的,但如果已创建的实体比较多,比如10个实体以上,涉及修改的地方比较多的 ...

  5. .NET基础篇——Entity Framework 数据转换层通用类

    在实现基础的三层开发的时候,大家时常会在数据层对每个实体进行CRUD的操作,其中存在相当多的重复代码.为了减少重复代码的出现,通常都会定义一个共用类,实现相似的操作,下面为大家介绍一下Entity F ...

  6. asp.net mvc常用的数据注解和验证以及entity framework数据映射

    终于有时间整理一下asp.net mvc 和 entity framework 方面的素材了. 闲话少说,步入正题: 下面是model层的管理员信息表,也是大伙比较常用到的,看看下面的代码大伙应该不会 ...

  7. .NET批量大数据插入性能分析及比较

    数据插入使用了以下几种方式 1. 逐条数据插入2. 拼接sql语句批量插入3. 拼接sql语句并使用Transaction4. 拼接sql语句并使用SqlTransaction5. 使用DataAda ...

  8. 大数据应用之HBase数据插入性能优化之多线程并行插入测试案例

    一.引言: 上篇文章提起关于HBase插入性能优化设计到的五个参数,从参数配置的角度给大家提供了一个性能测试环境的实验代码.根据网友的反馈,基于单线程的模式实现的数据插入毕竟有限.通过个人实测,在我的 ...

  9. Lazy<T>在Entity Framework中的性能优化实践(附源码)

    在使用EF的过程中,导航属性的lazy load机制,能够减少对数据库的不必要的访问.只有当你使用到导航属性的时候,才会访问数据库.但是这个只是对于单个实体而言,而不适用于显示列表数据的情况. 这篇文 ...

随机推荐

  1. Powershell Exchange Server UP Time

    Server up time Get-ExchangeServer | where{$_.name -like'wendy*'} | %{ if(Test-Connection $_.name -Co ...

  2. MVC异步消息推送机制

    在MVC里面,有异步控制器,可以实现模拟消息推送机制功能 1.控制器要继承至AsyncController,如 public class RealTimeController : AsyncContr ...

  3. js 中和c类似

    w <script type="text/javascript"> <!-- var w = 123 alert(w) function fun(){ alert ...

  4. 使用electron进行原生应用的打包(2)---主进程与渲染进程之间的通信

    上一篇讲了使用electron进行打包的配置相关文件,这篇主要讲electron中很重要的通信方式. 首先解释一个概念: electron打包的应用包含两个部分 electron的环境(node),也 ...

  5. MyBatis generator 生成生成dao model mappper

    MyBatis GeneratorXML配置文件参考 在最常见的用例中,MyBatis Generator(MBG)由XML配置文件驱动. 配置文件告诉MBG: 如何连接到数据库 什么对象要生成,以及 ...

  6. 一篇搞定vue请求和跨域

    vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基本Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对v ...

  7. Mysql数据库(表)的导出和导入小结

    Why? 有人因为想看导出的开房记录库文件,然后学会了Mysql数据库文件的导入操作~: 有人因为工作原因,要用到数据库的备份与导入,然后应需学会了骚操作~: 我因为~~emmm 想看某个导出的库文件 ...

  8. DRF(5) - 频率组件、url注册器、响应器、分页器

    一.频率组件 1.使用DRF简单频率控制实现对用户进行访问频率控制 1)导入模块,定义频率类并继承SimpleRateThrottle # 导入模块 from rest_framework.throt ...

  9. Hbase 学习笔记1----shell

    Hbase 是一个分布式的.面向列的开源数据库,其实现是建立在google 的bigTable 理论之上,并基于hadoop HDFS文件系统.     Hbase不同于一般的关系型数据库(RDBMS ...

  10. 第六课 GDB调试 (上)

    1序言: 1.初学者经过学习前面的Makefile知识,信心满满,内心觉得应该要好好学习不单掌握语言的编写,也要学会相对应的工具调高开发效率.有时我们写出来的代码经过执行结果却跟我们预期不一样那怎么办 ...