C#SQL BulkCopy日期时间插入问题

时间:2018-08-21 23:18:01

标签: c# sql-server datetime sqlbulkcopy

我在将包含C#DateTime对象的数据表批量插入SQL Server数据库中时遇到问题,并不断出现以下错误:

  

数据源中String类型的给定值不能转换为指定目标列的datetime类型。

我运行了一个堆栈跟踪以查看表试图插入的内容(如下图)

Datatable insert

这是我用来解析日期的代码

 SInstance s = new SInstance {                    
                Timestamp = DateTime.ParseExact(values[0],"yyyy-MM-dd",null),
               //other property initializations                   
            };

其中

values[0] = "2018-08-08"

大多数其他答案是使用适当的格式手动配置数据表,但是这些表是在运行时使用类属性动态生成的,因此对任何内容进行硬编码都是不可能的。这是批量复制代码段

的代码
DataTable dt = DBOHelper.GenerateDataTable(dbObjects);

using (SqlBulkCopy sqlBulk = _database.BulkCopySQL())
{
    sqlBulk.DestinationTableName = table;
    sqlBulk.BatchSize = commitBatchSize;

    try
    {
        sqlBulk.WriteToServer(dt);
        dt.Dispose();
    }
    catch (Exception e)
    {
        AuditEngine.Instance.LogError("DatabaseEngine", "SQLBulkInsert", e.Message);
        return 0;
    }
}

和表生成器功能:

public static DataTable GenerateDataTable<T>(DBOCollection<T> dBOCollection)
        where T : DbObject
{
    DataTable dt = GenerateEmptyDataTable<T>();

    List<PropertyInfo> props = GetDBODataMemberProperties<T>();

    foreach (DbObject dbo in dBOCollection)
    {
        DataRow row = dt.NewRow();

        for (int i = 0; i < props.Count; i++)
        {
            row[i] = props[i].GetValue(dbo);
        }

        dt.Rows.Add(row);
    }

    return dt;
}

public static DataTable GenerateEmptyDataTable<T>()
        where T : DbObject
{
    DataTable dt = new DataTable();

    List<PropertyInfo> properties = GetDBODataMemberProperties<T>();

    foreach (PropertyInfo p in properties)
    {              
        dt.Columns.Add(p.Name, p.PropertyType);
    }

    return dt;
}

对于没有日期字段的对象,一切都可以正常工作,但是由于某种原因,我尝试的所有日期格式都会引发错误。预先感谢您的任何建议。

2 个答案:

答案 0 :(得分:0)

您使用的是TimeStamp,时间戳将产生字符串,这意味着如果执行以下操作:

Timestamp = DateTime.ParseExact(values[0],"yyyy-MM-dd",null)

您将得到一个字符串。仅供参考,下面是生成时间戳的方法:

public static String GetTimestamp(this DateTime value)
{
    return value.ToString("yyyyMMddHHmmssfff");
}

您需要做的就是将其更改为:

DateTime = DateTime.ParseExact(values[0],"yyyy-MM-dd",null);

我建议:

DateTime date; 
 if(DateTime.TryParseExact(values[0], "yyyy-MM-dd", 
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.None, out date)
{
   //succeeded, date contains the value
}
else
{
  //error
}

答案 1 :(得分:0)

答案是在运行时生成属性名称列表,然后将它们映射到SqlBulkCopy对象(仅在数据库列名称和属性名称匹配时有效)

DataTable dt = DBOHelper.GenerateDataTable(dbObjects, out List<string> propertyNames);

        using (SqlBulkCopy sqlBulk = _database.BulkCopySQL())
        {
            sqlBulk.DestinationTableName = table;
            sqlBulk.BatchSize = commitBatchSize;

            foreach (string s in propertyNames)
            {
                sqlBulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping(s, s));
            }

            try
            {
                sqlBulk.WriteToServer(dt);
                dt.Dispose();
            }
            catch (Exception e)
            {
                AuditEngine.Instance.LogError("DatabaseEngine", "SQLBulkInsert", e.Message);
                return 0;
            }
        }
相关问题