SQLBulkCopy是繼承SQLClient空間下的一個特殊類,它可以幫助我們以映射的方式把DataTable和DataReader資料大批量導入到資料庫對應表中
public void Inert2DBBySqlBulkCopy(DataTable data, string tableName)
{
BaseDao basdd = new BaseDao();
using (SqlConnection conn = new SqlConnection(basdd.SqlNormMap.DataSource.ConnectionString))
{
if (conn.State != ConnectionState.Open)
conn.Open();
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(conn))
{
sqlBulkCopy.ColumnMappings.Add(0, "CarModelID");
sqlBulkCopy.ColumnMappings.Add(1, "TranConfID");
sqlBulkCopy.ColumnMappings.Add(2, "TranValue");
sqlBulkCopy.ColumnMappings.Add(3, "CreatorID");
sqlBulkCopy.ColumnMappings.Add(4, "Creator");
sqlBulkCopy.ColumnMappings.Add(5, "OptDataType");
sqlBulkCopy.BatchSize = data.Rows.Count;
sqlBulkCopy.BulkCopyTimeout = 30;
sqlBulkCopy.DestinationTableName = tableName;
sqlBulkCopy.WriteToServer(data);
}
if (conn.State != ConnectionState.Closed)
conn.Close();
}
}
其中要注意都是:
Table表中的字段名稱,字段順序,字段類型 必須和插入的sqlBulkCopy.ColumnMappings.Add的插入順序是一模一樣的,如下圖,自定義一個Class
public class JJJModel
{
public int? CarModelID { get; set; }
public int TranConfID { get; set; }
public string TranValue { get; set; }
public int CreatorID { get; set; }
public string Creator { get; set; }
public int OptDataType { get; set; }
}
插入的時候的代碼
//比對款式Id和配置ID 拼成二維表資料
for (int i = 0; i < listCarModelID.Count(); i++)
{
msindex = i;
for (int j = 0; j < listTranF.Count(); j++)
{
JJJModel jj = new JJJModel();
jj.CarModelID = Convert.ToInt32(listCarModelID[i]); //款型ID
jj.TranConfID = Convert.ToInt32(listTranF[j].ToString()); //配置ID
jj.TranValue = dtCMTranConf.Rows[i][j + 2].ToString().ToUpper();//值
jj.CreatorID = UserId;
jj.Creator = UserName;
jj.OptDataType = CarConst.OptDataType20;
listTranExcel.Add(jj);
}
}
異常資訊:樓主剛開始寫的時候也是按照上邊開發,百萬資料資料也是輕輕松松分分鐘搞定的。可是後來,産品有提到一個要求,就是要大批量更新資料,而且也是速度很快的時間内完成。
解決SQLBulkCopy批量更新問題:
于是就想先删除 那些要插入的資料,再批量插入要更新的資料,于是乎就捋起胳膊大幹一場,當然删除和批量插入肯定是同一張表(Table_A),也肯定是在同一個事務中,後來,後來竟然插入不成功,
就一直在sqlBulkCopy.WriteToServer(data);這句代碼裡邊一直轉悠,一直到sql連接配接逾時結束調試程式。我就郁了個悶的,同樣的代碼怎麼會出現這個問題。
後來仔細檢視對比一下,原來問題是由于對同一個表(Table_A) 先删除,再批量插入的時候 都是在同一個事務中 ,因為删除的時候 就把表給lock了,當然隻能插入失敗了.
那怎麼辦呢,于是樓主就扔然 還讓先删除,再插入 在同一個事務中,隻是在資料做了個操作,建立一個同樣和目标表(Table_A)一樣的臨時表(Table_Temp),在執行事務開始時候,
先把要插入的資料插入到臨時表Table_Temp,然後執行存儲過程,再存儲過程中 删除目标表(Table_A)中的存在于臨時表(Table_Temp)裡邊的ID條件資料.
然後再用Insert Into 目标表(Table_A) select from 臨時表(Table_Temp) 的方法把臨時表的資料插入到目标表(Table_A)中.這樣就妥妥的完成了。
PS:存儲過程中寫個事務,完成不完成都要把臨時表(Table_Temp)的資料清空哦 ,這個可不能忘記了