FastMember和可空属性

时间:2016-08-17 07:48:45

标签: c# reflection sqlbulkcopy fastmember

我有使用fastmember的问题,我的类有一个公共可空属性(datetime),但当我尝试将其插入db时,列值为空字符串而不是null ,导致异常被抛出,关于如何使列值为null的任何想法?

public class MyClass
{
    public DateTime? MyDate {get;set;}
}

DataTable testTable = new DataTable();
using (var reader = ObjectReader.Create(myClassList))
{
    testTable.Load(reader);
}

 using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["connection"].ConnectionString))
 {
     SqlTransaction transaction = null;
     connection.Open();
     try
     {
         transaction = connection.BeginTransaction();
         using (var sqlBulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, transaction))
         {
              sqlBulkCopy.BulkCopyTimeout = 0;
              sqlBulkCopy.BatchSize = batchSize;
              sqlBulkCopy.DestinationTableName = "myTable";
              for (var cols = 0; cols < testTable.Columns.Count; cols++)
              {
                   sqlBulkCopy.ColumnMappings.Add(cols, cols);
              }

              sqlBulkCopy.WriteToServer(testTable);
          }
          transaction.Commit();
      }
      catch (Exception ex)
      {
          transaction.Rollback();
          throw ex;
      }
  }

如果releaseate为null,那么它总是将它作为空字符串而不是null放入表中,有没有办法强制它为空?或者在sql批量副本中将空字符串解释为null?

1 个答案:

答案 0 :(得分:1)

很抱歉打破一个有点老问题。但是这里有一些突出的东西。使用DataTable(当FastMember阅读器基本上设计为直接推入SqlBulkCopy时),0超时值(通常不明智)以及此处交易的奇怪用法(BCP将默认情况下使用它自己的内部事务,如果它在任何时候失败,它会自行回滚)。

关于null问题,如果对象属性的排序与数据库中属性的排序不匹配,则会发生这种情况。解决方案?  FastMember!使用它来迭代您的类属性并构建映射。以下是适用于您的代码的清理版本:

using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connection"].ConnectionString))
using (var bcp = new SqlBulkCopy(conn))
using (var rd = ObjectReader.Create(myClassList))))
{
    Type type = typeof(T);
    var accessor = TypeAccessor.Create(type);
    var members = accessor.GetMembers();

    foreach (var member in members)
    {
        bcp.ColumnMappings.Add(new SqlBulkCopyColumnMapping(member.Name, member.Name));
    }

    conn.Open();

    bcp.BatchSize = 10000;
    bcp.DestinationTableName = "myTable";

    bcp.WriteToServer(rd);
}
  

注意:这是.NET兼容代码,因此您可能需要调整Type type代码以符合.NET Framework。但FastMember代码将是相同的。