最近做了一个.NET Framework 程序,将从远程接口请求的数据同步到sqlserver数据库中;当数据量小的时候,常规的添加操作是没什么问题的。但数据量比较大时(通常1000行及以上),会花费比较多的时间。这时SqlBulkCopy就能显著的解决这个问题。
1、SqlBulkCopy介绍
SqlBulkCopy是.NET中的一个包,用于将大批量数据添加到sqlserver数据库中,相比逐行插入它的速度更快,并且支持分批处理,失败事务回滚、设置延迟等。
2、SqlBulkCopy使用
这里封装了一个公共方法,用于将指定的数据插入到表中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
public void BulkInsert<T>(string connStr, string tableName, IEnumerable<T> datas, int batchSize, int timeout) { var dataList = new List<T>(datas); while (dataList.Count > 0) { int currentBatchSize = Math.Min(batchSize, dataList.Count); List<T> batchData = dataList.GetRange(0, currentBatchSize); using (var conn = new SqlConnection(connStr)) { conn.Open(); SqlTransaction tran = conn.BeginTransaction(); try { using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tran)) { bulkCopy.DestinationTableName = tableName; bulkCopy.BatchSize = batchSize; bulkCopy.BulkCopyTimeout = timeout; bulkCopy.EnableStreaming = true; var properties = typeof(T).GetProperties().OrderBy(p => p.MetadataToken).ToArray(); foreach (var prop in properties) { bulkCopy.ColumnMappings.Add(prop.Name, prop.Name); } using (var reader = ObjectReader.Create(batchData)) { bulkCopy.WriteToServer(reader); } } tran.Commit(); dataList.RemoveRange(0, currentBatchSize); } catch { tran.Rollback(); throw; } } } }
|
注意:在Modal中申明的实体需要和表中的顺序一一对应
举个例子:
Modal中定义User:
1 2 3 4 5 6
| public class User { public Guid UserId { get; set; } public string Username { get; set; } public string Hobby { get; set; } }
|
实际User表结构:

食用方式:
1 2 3 4 5 6
| var users = new List<User>(){ new User(){UserId = Guid.NewGuid(), Username = "小一", Hobby = "旅游"}, new User(){UserId = Guid.NewGuid(), Username = "小二", Hobby = "散步"} } string connStr = GetConnectionString(); BulkInsert(connStr, "dbo.user", users, 1000, 30);
|