C# 什么';SqlBulkCopy从实体中复制时,此数据表有何问题?
我知道下面的方法不适用于任何实体,不应强制使用 我发现了一个System.Data.Linq.Table扩展方法,它使用SqlBulkCopy插入数据。我正试图将其调整为实体框架,但它抛出了一个奇怪的异常,而原始版本适用于LINQtoSQL数据类。到目前为止,我还没有发现这个缺陷,它发生在任何SQL表上,在1-1映射中。你能帮我吗C# 什么';SqlBulkCopy从实体中复制时,此数据表有何问题?,c#,.net,linq,entity-framework,datatable,C#,.net,Linq,Entity Framework,Datatable,我知道下面的方法不适用于任何实体,不应强制使用 我发现了一个System.Data.Linq.Table扩展方法,它使用SqlBulkCopy插入数据。我正试图将其调整为实体框架,但它抛出了一个奇怪的异常,而原始版本适用于LINQtoSQL数据类。到目前为止,我还没有发现这个缺陷,它发生在任何SQL表上,在1-1映射中。你能帮我吗 public static class ObjectQueryExtensions { public static string GetName<TEn
public static class ObjectQueryExtensions
{
public static string GetName<TEntity>(
this ObjectQuery<TEntity> objectQuery)
where TEntity : class
{
var tableNameGroup = new Regex(@"FROM\s([^\s]*)\s"
, RegexOptions.IgnoreCase);
var sql = objectQuery.ToTraceString();
var tableNameGroupMatch = tableNameGroup.Match(sql);
return tableNameGroupMatch.Groups[1].Value;
}
public static void BulkInsert<TEntity>(
this ObjectQuery<TEntity> objectQuery
, IEnumerable<TEntity> items)
where TEntity : class
{
using (var dt = new DataTable())
{
var properties = typeof(TEntity)
.GetProperties()
.Where(property => property.Name != "EntityKey")
.Where(property => property.Name != "EntityState")
;
foreach (var property in properties)
{
dt.Columns.Add(property.Name
, Nullable.GetUnderlyingType(property.PropertyType)
?? property.PropertyType);
}
foreach (var t in items)
{
DataRow row = dt.NewRow();
foreach (var info in properties)
{
row[info.Name] = info.GetValue(t, null) ?? DBNull.Value;
}
dt.Rows.Add(row);
}
var entityConnection = (EntityConnection)objectQuery
.Context.Connection;
using (var sqlBulkCopy = new SqlBulkCopy(
entityConnection.StoreConnection.ConnectionString))
{
sqlBulkCopy.DestinationTableName = objectQuery.GetName();
sqlBulkCopy.WriteToServer(dt);
}
}
}
}
公共静态类ObjectQueryExtensions
{
公共静态字符串GetName(
此ObjectQuery(ObjectQuery)
地点:班级
{
var tableNameGroup=new Regex(@“FROM\s([^\s]*)\s”
,RegexOptions.IgnoreCase);
var sql=objectQuery.ToTraceString();
var tableNameGroupMatch=tableNameGroup.Match(sql);
返回tableNameGroupMatch.Groups[1]。值;
}
公共静态空白填充(
此ObjectQuery是ObjectQuery
,IEnumerable items)
地点:班级
{
使用(var dt=new DataTable())
{
var属性=类型(强度)
.GetProperties()
.Where(property=>property.Name!=“EntityKey”)
.Where(property=>property.Name!=“EntityState”)
;
foreach(属性中的var属性)
{
dt.Columns.Add(property.Name
,可为null.GetUnderlyingType(property.PropertyType)
??属性。属性类型);
}
foreach(项目中的var t)
{
DataRow row=dt.NewRow();
foreach(属性中的var信息)
{
行[info.Name]=info.GetValue(t,null)??DBNull.Value;
}
dt.行。添加(行);
}
var entityConnection=(entityConnection)objectQuery
.Context.Connection;
使用(var sqlBulkCopy=newsqlbulkcopy(
entityConnection.StoreConnection.ConnectionString)
{
sqlBulkCopy.DestinationTableName=objectQuery.GetName();
sqlBulkCopy.WriteToServer(dt);
}
}
}
}
例外
测试方法LinqExtensionsTest.ObjectQueryExtensionsTest.BulkInsertTest引发异常:System.InvalidOperationException:数据源中Int64类型的给定值无法转换为指定目标列的datetime类型。-->System.InvalidCastException:无法将参数值从Int64转换为DateTime。-->System.InvalidCastException:从“Int64”到“DateTime”的转换无效
堆栈跟踪
System.Int64.System.IConvertible.ToDateTime(IFormatProvider)
System.Convert.ChangeType(对象值、类型conversionType、IFormatProvider)
System.Data.SqlClient.SqlParameter.ImproveValue(对象值,元类型destinationType)
System.Data.SqlClient.SqlParameter.ImproveValue(对象值,元类型destinationType)
System.Data.SqlClient.SqlBulkCopy.ConvertValue(对象值,_sqlmetadatametadata)
System.Data.SqlClient.SqlBulkCopy.ConvertValue(对象值,_sqlmetadatametadata)
System.Data.SqlClient.SqlBulkCopy.WriteToServerInternal()
System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServer(Int32 columnCount)
System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable表,DataRowState rowState)
System.Data.SqlClient.SqlBulkCopy.WriteToServer(数据表)
LinqExtensions\LinqExtensions\ObjectQueryExtensions.BulkInsert[TEntity](ObjectQuery1 ObjectQuery,IEnumerable
1项)在LinqExtensions\LinqExtensions\ObjectQueryExtensions.cs中:第60行
LinqExtensions\LinqExtensionsTest\ObjectQueryExtensionsTest中的LinqExtensionsTest.ObjectQueryExtensionsTest.BulkInsertTest():第88行
您得到的异常几乎说明了一切:在实体对象中,您有一个类型为
Int64
的属性,该属性在数据库中定义为DateTime
,并且无法从一个隐式转换到另一个。您真的打算将该数据库列表示为整数吗?可能这只是实体类定义中的一个错误。我知道您是从实体创建了DataTable,但我的建议是检查DataTable中列的顺序是否与表中列的顺序相同(可能您更改了数据库,没有更新模型)。如果不相同,则可能存在不匹配的数据类型,并遇到无效强制转换错误。这事发生在我身上;) 你的答案是最明显的,但我很难相信,因为我使用Visual Studio实体设计器创建了实体类,它不会有这样的错误。我还重新检查了DataTable和Sql Profiler中的每个字段,你的怀疑没有得到证实。这显然是一个类型错误,而且它不是来自设计师。但这仍然是一个类型错误。它不在这里显示的代码中,但在您的项目中。因此,您必须查找堆栈并找到错误。我必须进入.NET代码以了解如何规避此问题。没错,如果您对edmx文件中未镜像的数据库进行任何修改,将导致您出现此问题。如果edmx上的列顺序与数据库表上的列顺序不匹配,则会导致出现此类异常。有关实体和数据库中不同列顺序的解决方案,请参阅。