SqlBulkCopy是.NET Framework 2.0新增的類,位於命名空間System.Data.SqlClient下,主要提供把其他數據源的數據有效批量的加載到SQL Server表中的功能。類似與 Microsoft SQL Server 包中名為 bcp 的命令行應用程序。但是使用 SqlBulkCopy 類可以編寫托管代碼解決方案,性能上優於bcp命令行應用程序,更優於如Insert方式向SQL Server表加載大量數據。SqlBulkCopy可以應用到大批量數據的轉移上,而不管數據源是什么。
之前在做winform開發的時候,發現當datagridview數據量比較大的時候,用for循環非常耗時間與性能,通過查閱資料,了解到了SqlBulkCopy這種批量的數據轉移工具。
下述代碼實現了datagridview的批量數據插入。
如果datagridview的列與數據庫中的表結構不能完全對應的話,我們需要先將datagridview數據存放到一個DataTable 中,注意DataTable 中的列需要與即將插入的表的列類型兼容,名稱與列順序完全一樣。自增列隨便填寫一個int類型的值即可,也可不寫,如果沒給自增列指定值的話,在后續的表映射關系中需要明確指出對應關系。因為我這里是用循環來指定表對應關系的,所以對table的字段有嚴格的要求,其實也可以與數據庫表中的字段名不一樣,但這樣就需要具體指出表之間的對應關系。
DataTable table = new DataTable();
table.Columns.AddRange(new DataColumn[]{
new DataColumn("flow_id",typeof(int)),
new DataColumn("sheet_no",typeof(string)),
new DataColumn("item_no",typeof(string)),
new DataColumn("unit_no",typeof(string)),
new DataColumn("unit_factor",typeof(string)),
new DataColumn("in_price",typeof(string)),
new DataColumn("order_qnty",typeof(string)),
new DataColumn("sub_amount",typeof(string)),
new DataColumn("real_qty",typeof(string)),
new DataColumn("tax_rate",typeof(string)),
new DataColumn("pay_percent",typeof(string)),
new DataColumn("out_qty",typeof(string))});
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow r = dt.Rows[i];
table.Rows.Add(i, sheet_no, r["item_no"], r["unit_no"], r["unit_factor"], r["in_price"], r["order_qnty"], r["sub_amount"], r["real_qty"], r["tax_rate"], r["pay_percent"], r["out_qty"]);
}
//開始數據保存邏輯
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlTransaction tran = conn.BeginTransaction();//開啟事務
//在插入數據的同時檢查約束,如果發生錯誤調用sqlbulkTransaction事務
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.CheckConstraints, tran);
bulkCopy.DestinationTableName = "***";//***代表要插入數據的表名
foreach (DataColumn dc in table.Columns) //傳入上述table
{
bulkCopy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName);//將table中的列與數據庫表這的列一一對應
}
try
{
bulkCopy.WriteToServer(table);
tran.Commit();
}
catch (Exception ex)
{
tran.Rollback();
}
finally
{
bulkCopy.Close();
conn.Close();
}