zoukankan      html  css  js  c++  java
  • ef 多条数据插入处理方案(据说还有更好的)

     首先上个错误的版本。

     1         public int SaveMany(List<Lotterys> dataList)
     2         {
     3             using (var db = base.NewDB())
     4             {
     5                 if (dataList.Count == 0)
     6                     return 0;
     7 
     8                 int count = 0;
     9                 foreach (var item in dataList)
    10                 {
    11                     db.Entry(item).State = System.Data.Entity.EntityState.Added;
    12                     count += db.SaveChanges();
    13                 }
    14                 return count;
    15             }
    16         }
    View Code

       为什么错误?

    许多人应该看出来了。最大的错误就是每保存一条数据就执行SaveChanges()方法,执行一次SaveChanges()方法要耗费很多时间。并且这个思路也不对。SaveChanges,是事务提交,提交一次会自动释放数据库连接。

    我们先试试这种写法1W条数据要多久。估计要炸!(PS:测试环境为wind10,VS2015,EF6.0,MySql,电脑内存8G,Cpu I7-7500U。就一般工作电脑就是了)

    终于是出来了...7分钟...

    现在进行第二种错误版本。

     1         public int SaveMany(List<Lotterys> dataList)
     2         {
     3             using (var db = base.NewDB())
     4             {
     5                 if (dataList.Count == 0)
     6                     return 0;
     7 
     8                 foreach (var item in dataList)
     9                 {
    10                     db.Entry(item).State = System.Data.Entity.EntityState.Added;
    11                 }
    12                 return db.SaveChanges();
    13             }
    14         }
    View Code

    这个版本,我自己也踩中了,还是读书少...

    优化在将SaveChanges()移出循环,首先将数据插入进EF内存数据中,再执行SaveChanges(),将这些数据提交进数据库,进行持久化。这个坑怎么填稍后说明。

    测试下...1分钟15秒...

    这个版本的坑在于循环,我们将数据循环插入内存数据中这边浪费了很多时间。看终极版本。

     1         public int SaveMany(List<Lotterys> dataList)
     2         {
     3             using (var db = base.NewDB())
     4             {
     5                 if (dataList.Count == 0)
     6                     return 0;
     7 
     8                 db.Set<Lotterys>().AddRange(dataList);
     9                 return db.SaveChanges();
    10             }
    11         }
    View Code

    老规矩,测试下...

    这次是直接使用EF中内置方法db.Set<T>().AddRange()方法。这个方法说明是将数据放入EF基础数据中,并将其标记为添加状态也就是 db.Entry<T>(entity).State = System.Data.Entity.EntityState.Added;并在执行SaveChange()时将数据提交到数据库。

    可以看到在没有循环的时候数据加入极快。保存也非常的迅速。

    我这次多截图将程序运行的状态显示出来了,大家可以看到在执行建立数据,和保存数据这边CPU使用率是暴涨的,并且结果也很快8秒,说明程序是充分利用了系统资源的。

    再测试个10W条嘿嘿...

    10W条数据1分30秒,经多次测量,10W条数据一般在90-120(秒)之间。

    好了坑填完了。欢迎讨论。

  • 相关阅读:
    性能碾压 POI !利用模板语法快速生成 Excel 报表
    大庆金桥:基于 SpreadJS 开发实现计量器具检定证书的在线生成与打印
    厦门科云:构建基于 SpreadJS 的管理会计综合实训平台
    为什么 Vue 更符合这个时代的大势所趋
    嵌入SpreadJS,赋能计量器具检定信息化
    GcExcel:比 Apache POI 速度更快、性能更高
    使用SpreadJS 开发在线问卷系统,构筑CCP(云数据采集)平台
    首厚智能:嵌入 SpreadJS 表格组件,搭建实验室信息管理系统(LIMS)
    企业数字化转型:用 SpreadJS 打造互通互链的电力系统物联网
    悲观锁和乐观锁
  • 原文地址:https://www.cnblogs.com/FlyStupidBird/p/8629313.html
Copyright © 2011-2022 走看看