zoukankan      html  css  js  c++  java
  • EF架构~数据分批批量提交

    回到目录

    对于大数据量提交,包括插入,更新和删除,我始终不建议用EF自带的方法,因为它会增加与数据库的交互次数,一般地,EF的一个上下文在提交时会打开一个数据连接,然后把转换成的SQL语句一条一条的发到数据库端,然后去提交,试想,如果你的数据量达到万级别(更不用说百万,千万数据了),那对数据库的压力是很大的,所以,我将EF批量操作语句进行了改版,并起名为BulkInsert,BulkUpdate和BulkDelete,事实上,在我之前的版本中并没有涉及到批次提交的概念,直到遇到了实际的问题,当你使用BulkInsert时,如果数据达到4万之前,那在SQL的解释时,也是很有压力的,有多情况下会超时,当然这与你的数据库服务器有关,但为了性能与安全,我还是决定将Bulk操作变为分批提交,即将4W进行分解,分用1W数据量提交一次,这样,对数据库的压力就小一些。看看我的改版吧。

         public void BulkInsert(IEnumerable<TEntity> item)
            {
                DataPageProcess(item, (currentItems) =>
                {
                    ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超时
                    _Db.Database.ExecuteSqlCommand(DoSQL(currentItems, SQLType.Insert));
                });
            }
    
            public void BulkDelete(IEnumerable<TEntity> item)
            {
                DataPageProcess(item, (currentItems) =>
                {
                    ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超时
                    _Db.Database.ExecuteSqlCommand(DoSQL(currentItems, SQLType.Delete));
                });
            }
         public void BulkUpdate(IEnumerable<TEntity> item)
            {
                DataPageProcess(item, (currentItems) =>
                {
                    ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超时
                    _Db.Database.ExecuteSqlCommand(DoSQL(currentItems, SQLType.Update));
                });
            }
            /// <summary>
            /// 分页进行数据提交的逻辑
            /// </summary>
            /// <param name="item">原列表</param>
            /// <param name="method">处理方法</param>
            /// <param name="currentItem">要进行处理的新列表</param>
            private void DataPageProcess(IEnumerable<TEntity> item, Action<IEnumerable<TEntity>> method)
            {
                if (item != null && item.Count() > 0)
                {
                    DataTotalCount = item.Count();
                    this.DataTotalPages = item.Count() / DataPageSize;
                    if (DataTotalCount % DataPageSize > 0)
                        DataTotalPages += 1;
                    for (int pageIndex = 1; pageIndex <= DataTotalPages; pageIndex++)
                    {
                        var currentItems = item.Skip((pageIndex - 1) * DataPageSize).Take(DataPageSize).ToList();
                        method(currentItems);
                    }
                }
            }

    我们可以看到,改版后的方法,没有直接把集合item传递给方法ExecuteSqlCommand去执行,而去调用了一个方法,这个方法然后传入一个委托,然这个委托的

    输入参数是一个分页的数据集合,这时你的ExecuteSqlCommand方法接入的集合参数将是一个分了页之后的小集合,呵呵。

    对于一次提交的数量,你可以在类中去定义,它类似于分页,所以,我通常叫这个方法为数据分页提交!

        #region Fields
            /// <summary>
            /// 数据总数
            /// </summary>
            int DataTotalCount = 0;
    
            /// <summary>
            /// 数据总页数
            /// </summary>
            int DataTotalPages = 0;
    
            /// <summary>
            /// 数据页面大小(每次向数据库提交的记录数)
            /// </summary>
            int DataPageSize = 10000;
            #endregion

    如果你希望得到BlukInsert的完整方法,请关注本人的EF架构系列

    回到目录

  • 相关阅读:
    java基础之条件运算符
    java基础之x++与++x
    java基础之三种注释及API帮助文档的生成
    java基础之类型转换及常量的应用
    java基础之数据类型
    java基础之标识符
    生活小插曲(长篇连载,持续更新ing)^_^
    记录那个刚毕业,还不太富裕的那个人的生活
    记录两次小组会议总结
    这是大娃笔记里的一首散文诗
  • 原文地址:https://www.cnblogs.com/lori/p/3278921.html
Copyright © 2011-2022 走看看