dapper 使用sqlbulkcopy,50秒插入百万数据

在netcore中常常使用的EF,Dapper等orm框架,在做批量数据插入的时候,一般都是两种操作;

1:逐行插入,insert into....

2:批量插入。

最近项目中遇到个问题,需要同时插入大量的数据,数据量达到了百万级,使用传统的方式性能上完全不达标,不知道大家试过没有尼,使用dapper或者ef一次性插入一百万的数据,总耗时8分钟左右,这还是优化过的方案。

考虑之下,让我想起了很早之前Ado.Net中使用的复制,粘贴,大数据拷贝。sqlbulkcopy

dapper使用SqlBulkcopy需要引用

仔细研究之下,在考虑是不是可以和Dapper混合使用尼。经过几个小时的研究逐梦,做了如下封装,可以直接使用。

public void InsertBatchTest<T>(IEnumerable<T> entityList, IDbTransaction transaction = null) where T:class
        {
            using (IDbConnection conn = new SqlConnection(connection))
            {
                var tbName = string.Format("dbo.{0}", typeof(T).Name);
                var trans = (SqlTransaction)transaction;
                using (var bulkCopy = new SqlBulkCopy(conn as SqlConnection, SqlBulkCopyOptions.TableLock,trans))
                {
                    bulkCopy.BatchSize = 10000;
                    bulkCopy.BulkCopyTimeout = 60;
                    bulkCopy.DestinationTableName = tbName;
                    var table = new DataTable();
                    DapperExtensions.Sql.ISqlGenerator sqlGenerator = new SqlGeneratorImpl(new DapperExtensionsConfiguration());
                    var classMap = sqlGenerator.Configuration.GetMap<T>();
                    var props = classMap.Properties.Where(x => x.Ignored == false).ToArray();
                    foreach (var propertyInfo in props)
                    {
                        bulkCopy.ColumnMappings.Add(propertyInfo.Name, propertyInfo.Name);
                        table.Columns.Add(propertyInfo.Name, Nullable.GetUnderlyingType(propertyInfo.PropertyInfo.PropertyType) ?? propertyInfo.PropertyInfo.PropertyType);
                    }
                    var values = new object[props.Count()];
                    foreach (var itemm in entityList)
                    {
                        for (var i = 0; i < values.Length; i++)
                        {
                            values[i] = props[i].PropertyInfo.GetValue(itemm, null);
                        }
                        table.Rows.Add(values);
                    }

                    try
                    {
                        conn.Open();
                        bulkCopy.WriteToServer(table);
                    }
                    catch (Exception)
                    {
                        conn.Close();
                        conn.Dispose();
                    }
                   
                }
            }
        }

sqlbulkcopy的原理就是先写入数据库表的内存中,在插入数据表,经过几十次的测试,基本耗时都在50多秒。

代码以封装好,大家可以直接使用。个人小网站,大家可以留言提点建议(感激不尽):https://www.51wzuan.cn/

posted @   夜钓星云  阅读(175)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示