zoukankan      html  css  js  c++  java
  • 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 将导致目标表该自增列的自增失效; 

  • 相关阅读:
    Delphi XE4 FireMonkey 开发 IOS APP 发布到 AppStore 最后一步.
    Native iOS Control Delphi XE4
    Delphi XE4 iAD Framework 支持.
    using IOS API with Delphi XE4
    GoF23种设计模式之行为型模式之命令模式
    Android青翼蝠王之ContentProvider
    Android白眉鹰王之BroadcastReceiver
    Android倚天剑之Notification之亮剑IOS
    Android紫衫龙王之Activity
    GoF23种设计模式之行为型模式之访问者模式
  • 原文地址:https://www.cnblogs.com/mushishi/p/3592558.html
Copyright © 2011-2022 走看看