C# 平时碰见的问题【1】
1. SqlBulkCopy
可以利用這個類實現快速大批量新增數據的效果, 但在使用過程中發現了一個問題: 無法將數據源中的DateTime類型轉換成數據庫中的int類型?
看起來就是數據列不對應導致的, 不過一開始也不確定,后面試驗確定 SqlBulkCopy 自建的DataTable數據源writeToServer在未添加列與列的映射(ColumnMappings)時候即使列名一致 也并不是按列名寫入數據的,而是按列的索引進行添加的.
故解決方法有二個:
(1) 在自建的數據源DataTable中補充前面的列?(若列處于需要添加的字段后面 則不用);
(2) SqlBulkCopy 列映射集合中添加?sqlBulkCopy.ColumnMappings.Add(sourceColumn, destinationColumn); ?將每列與目標數據庫中的表關聯;
代碼如下:
1 public bool BulkAddData(string recordsString) 2 { 3 string[] records = recordsString.Split('$'); 4 bool boolIsSuccess = false; 5 DataTable dtTemp = new DataTable(); 6 dtTemp.Columns.Add(new DataColumn("ID", typeof(int))); //(1)ID在目標表中是自增列,并且是第一列 7 dtTemp.Columns.Add(new DataColumn("ScanUserID", typeof(int))); 8 dtTemp.Columns.Add(new DataColumn("ScanDate", typeof(DateTime))); 9 dtTemp.Columns.Add(new DataColumn("PO", typeof(string))); 10 dtTemp.Columns.Add(new DataColumn("SerialNumber", typeof(string))); 11 dtTemp.Columns.Add(new DataColumn("Container", typeof(string))); 12 dtTemp.Columns.Add(new DataColumn("ModelName", typeof(string))); 13 dtTemp.Columns.Add(new DataColumn("ModelID", typeof(int))); 14 15 foreach (string record in records) 16 { 17 DataRow dr = dtTemp.NewRow(); 18 string[] strModel = record.Split(','); 19 if (strModel.Length == 7) 20 { 21 // ID是自增列,不用賦值 22 dr["ScanUserID"] = int.Parse(strModel[0]); 23 dr["ScanDate"] = DateTime.Parse(strModel[1]); 24 dr["PO"] = strModel[2]; 25 dr["SerialNumber"] = strModel[3]; 26 dr["Container"] = strModel[4]; 27 dr["ModelName"] = strModel[5]; 28 dr["ModelID"] = int.Parse(strModel[6]); 29 } 30 dtTemp.Rows.Add(dr); 31 } 32 string strConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.ToString(); 33 using (SqlConnection conn = new SqlConnection(strConnectionString)) 34 { 35 conn.Open(); 36 SqlTransaction tran = conn.BeginTransaction(); 37 SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tran); 38 sqlBulkCopy.DestinationTableName = "T_DeliveryRecord"; 39 sqlBulkCopy.BatchSize = dtTemp.Rows.Count; 40 //(2) SqlBulkCopy 的表映射默認是按索引來和目標表對應的, 可通過以下方法強制對應 41 //sqlBulkCopy.ColumnMappings.Add("ScanUserID", "ScanUserID"); 42 //sqlBulkCopy.ColumnMappings.Add("ScanDate", "ScanDate"); 43 //sqlBulkCopy.ColumnMappings.Add("PO", "PO"); 44 //sqlBulkCopy.ColumnMappings.Add("SerialNumber", "SerialNumber"); 45 //sqlBulkCopy.ColumnMappings.Add("Container", "Container"); 46 //sqlBulkCopy.ColumnMappings.Add("ModelName", "ModelName"); 47 //sqlBulkCopy.ColumnMappings.Add("ModelID", "ModelID"); 48 49 try 50 { 51 sqlBulkCopy.WriteToServer(dtTemp); 52 tran.Commit(); 53 boolIsSuccess = true; 54 } 55 catch 56 { 57 tran.Rollback(); 58 boolIsSuccess = false; 59 } 60 finally 61 { 62 sqlBulkCopy.Close(); 63 } 64 } 65 66 return boolIsSuccess; 67 }?
ID是我的主鍵自增的列,位于表的第一位, 所以dtTemp中沒有ID列的時候 ScanDate的數據 將插入數據庫中的ScanUserID這個int類型的字段中出現上面提到的類型錯誤; 也就是列的不對應;
所以用方法(1) 解決本問題時, 臨時數據表的字段名及順序需要與目標表一致, 有默認值或者自增的字段不需要賦值;?當然這種情況的列只是作為占位,字段名不用對應也可以:如上面的dtTemp.Columns.Add(new DataColumn("ID", typeof(int))) 改成 dtTemp.Columns.Add(new DataColumn("AA", typeof(int))) 一樣也是可以的 );
attention: 注意如果給自增列賦值且SqlBulkCopyOptions.KeepIdentity?將導致目標表該自增列的自增失效;?
?
?
?
?
轉載于:https://www.cnblogs.com/mushishi/p/3592558.html
總結
以上是生活随笔為你收集整理的C# 平时碰见的问题【1】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【加】德鲁·卡宾森 - 质量效应2:升天
- 下一篇: poj 1015 Jury Compro