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 将导致目标表该自增列的自增失效; 

  • 相关阅读:
    2018-2019-2 网络对抗技术 20165230 Exp2 后门原理与实践
    BZOJ2038: [2009国家集训队]小Z的袜子(hose)
    BZOJ3262陌上花开 树状数组+Treap
    BZOJ1468 Tree 点分治入门练习题
    BZOJ2152 聪聪可可 点分治入门
    BZOJ3506 BZOJ1552 排序机械臂 Splay区间翻转(数组版自底向上的写法)
    BZOJ3196: Tyvj 1730 二逼平衡树 (线段树 + Treap 练习题)
    ZOJ2112 Dynamic Rankings 动态区间Kth(单点修改) 线段树+Treap写法
    OO第4单元总结&课程总结
    OO第三单无总结
  • 原文地址:https://www.cnblogs.com/mushishi/p/3592558.html
Copyright © 2011-2022 走看看