/// <summary> /// SqlBulkCopy 幫助類 /// </summary> public static class SqlBulkCopyHelper { /// <summary> /// 本地認證評估表建表SQL /// </summary> private const string CreateTemplateSql= @"[Id] [int] NOT NULL,[DisabilityCardId] [nvarchar](50) NOT NULL,[PartId] [nvarchar](32) NULL,[ProvinceCode] [nvarchar](4) NULL,[DisabilityLevel] [int] NULL,[DisabilityTypes] [nvarchar](16) NULL,[VisualDisabilityLevel] [int] NULL"; /// <summary> /// 本地認證評估更新SQL 這里采用的merge語言更新語句 你也可以使用 sql update 語句 /// </summary> private const string UpdateSql= @"Merge into DisabilityAssessmentInfo AS T Using #TmpTable AS S ON T.Id = S.Id WHEN MATCHED THEN UPDATE SET T.[DisabilityCardId]=S.[DisabilityCardId],T.[PartId]=S.[PartId],T.[ProvinceCode]=S.[ProvinceCode],T.[DisabilityLevel]=S.[DisabilityLevel],T.[DisabilityTypes]=S.[DisabilityTypes],T.[VisualDisabilityLevel]=S.[VisualDisabilityLevel];"; /// <summary> /// SqlBulkCopy 批量更新數據 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="crateTemplateSql"></param> /// <param name="updateSql"></param> public static void BulkUpdateData<T>(List<T> list, string crateTemplateSql,string updateSql) { var dataTable = ConvertToDataTable(list); ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlServerContext"].ConnectionString)) { using (var command = new SqlCommand("", conn)) { try { conn.Open(); //數據庫並創建一個臨時表來保存數據表的數據 command.CommandText =$" CREATE TABLE #TmpTable ({crateTemplateSql})"; command.ExecuteNonQuery(); //使用SqlBulkCopy 加載數據到臨時表中 using (var bulkCopy = new SqlBulkCopy(conn)) { foreach (DataColumn dcPrepped in dataTable.Columns) { bulkCopy.ColumnMappings.Add(dcPrepped.ColumnName, dcPrepped.ColumnName); } bulkCopy.BulkCopyTimeout = 660; bulkCopy.DestinationTableName = "#TmpTable"; bulkCopy.WriteToServer(dataTable); bulkCopy.Close(); } // 執行Command命令 使用臨時表的數據去更新目標表中的數據 然后刪除臨時表 command.CommandTimeout = 300; command.CommandText = updateSql; command.ExecuteNonQuery(); } finally { conn.Close(); } } } } /// <summary> /// SqlBulkCopy 批量插入數據 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="tableName"></param> public static void BulkInsertData<T>(List<T> list, string tableName) { var dataTable = ConvertToDataTable(list); ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); using (var bulkCopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["ServiceDataContext"].ConnectionString)) { foreach (DataColumn dcPrepped in dataTable.Columns) { bulkCopy.ColumnMappings.Add(dcPrepped.ColumnName, dcPrepped.ColumnName); } bulkCopy.BulkCopyTimeout = 660; bulkCopy.DestinationTableName = tableName; bulkCopy.WriteToServer(dataTable); } } public static DataTable ConvertToDataTable<T>(IList<T> data) { var properties = TypeDescriptor.GetProperties(typeof(T)); var table = new DataTable(); foreach (PropertyDescriptor prop in properties) table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); foreach (T item in data) { var row = table.NewRow(); foreach (PropertyDescriptor prop in properties) { row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; } table.Rows.Add(row); } return table; } }
使用SqlBulkCopy 可以很好的提高大量插入和修改數據的速度
引用博文:https://dotnetcodetips.com/Tip/68/SQL-Bulk-Upload-for-Inserts-or-Updates
https://stackoverflow.com/questions/8285666/delete-not-working-in-transaction-with-sql-bulk-insert