我在将包含C#DateTime
对象的数据表批量插入SQL Server数据库中时遇到问题,并不断出现以下错误:
数据源中String类型的给定值不能转换为指定目标列的datetime类型。
我运行了一个堆栈跟踪以查看表试图插入的内容(如下图)
这是我用来解析日期的代码
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;
}
对于没有日期字段的对象,一切都可以正常工作,但是由于某种原因,我尝试的所有日期格式都会引发错误。预先感谢您的任何建议。
答案 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;
}
}