EF临时表批量插入

1.概述

1.1 背景

使用EF框架对大量数据进行的插入或修改时,性能不高。而EF扩展库的批量修改每次只能修改特定的字段且约束字段也是特定的,当修改的数据是随机时,EF扩展库的批量修改满足我的需求。

1.2 目标

插入大量数据时,为提高性能,使用SqlBulkCopy临时表批量插入。修改大量数据是,先把修改的数据放到内存中,进行修改。然后删除数据库的数据,再用临时表一次插入。

2.解决方案

结合EF框架,使用SqlBulkCopy方法批量插入。

/// <summary>  
        /// 批量插入  
        /// </summary>  
        /// <typeparam name="T">泛型集合的类型</typeparam>  
        /// <param name=" dbContext ">连接对象</param>  
        /// <param name="tableName">将泛型集合插入到本地数据库表的表名</param>  
        /// <param name="list">要插入大泛型集合</param>  
        public static bool BulkInsert<T>(DbContext dbContext , string tableName, IList<T> list)
        {
            try
            {
                if (list == null || list.Count == 0) return true;
                if (dbContext.Database.Connection.State != ConnectionState.Open)
                {
                    dbContext.Database.Connection.Open(); //打开Connection连接  
                }
                using (var bulkCopy = new SqlBulkCopy(dbContext.Database.Connection.ConnectionString))
                {
                    bulkCopy.BatchSize = list.Count;
                    bulkCopy.DestinationTableName = tableName;

                    var table = new DataTable();
                    var props = TypeDescriptor.GetProperties(typeof(T))

                        .Cast<PropertyDescriptor>()
                        .Where(propertyInfo => propertyInfo.PropertyType.Namespace.Equals("System"))
                        .ToArray();

                    foreach (var propertyInfo in props)
                    {
                        bulkCopy.ColumnMappings.Add(propertyInfo.Name, propertyInfo.Name);
                        table.Columns.Add(propertyInfo.Name, Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType);
                    }

                    var values = new object[props.Length];
                    foreach (var item in list)
                    {
                        for (var i = 0; i < values.Length; i++)
                        {
                            values[i] = props[i].GetValue(item);
                        }
                        table.Rows.Add(values);
                    }

                    bulkCopy.WriteToServer(table);
                    if (dbContext.Database.Connection.State != ConnectionState.Closed)
                    {
                        dbContext.Database.Connection.Close(); //关闭Connection连接  
                    }
                    return true;
                }
            }
            catch (Exception ex)
            {
                if (dbContext.Database.Connection.State != ConnectionState.Closed)
                {
                    dbContext.Database.Connection.Close(); //关闭Connection连接  
                }
                return false;
            }
     }

 

调用方法如下:

List<Students> lstStu = new List< Students>();

// lstStu.Add(stu);

if (!DbHelper.BulkInsert< Students>( dbContext, "Students", lstTestStu))

{

     return false;

}

 

3. 解决方案分析

以上方案解决了批量插入的需求。但是要批量修改数据,需要先删除数据库数据,然后再批量插入。这个过程需要使用到事务来保证数据的一致性。这里我使用的是TransactionScope事务。有关TransactionScope使用说明可看“TransactionScope简介”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值