System.InvalidCastException:无法将类型为“System.String”的对象强制转换为“System.Int32”类型

时间:2017-06-13 02:49:43

标签: entity-framework

错误是

System.InvalidCastException occurred HResult=0x80004002 Message=Unable to 
   cast object of type 'System.String' to type 'System.Int32'. Source=<Cannot 
   evaluate the exception source> StackTrace: at 
Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleNullableDependentKeyValueFactory 1. TryCreateFromBuffer(ValueBuffer valueBuffer, TKey& key) at 
Microsoft.EntityFrameworkCore.Query.Internal.WeakReferenceIdentityMap`1.CreateIncludeKeyComparer(INavigation navigation, ValueBuffer valueBuffer)

我不确定如何解决/解决此错误。检查所有异常设置不会破坏错误,也不提供任何洞察力(可能是因为它不是我的代码?)。

使用EntityFrameworkCore.SQLServer 1.0.4。此时无法升级到较新版本,但在使用1.1.1时运行成功。

使用SQL Server 2016. VS 2017.

在复杂的IQueryable上调用ToList时会出现问题。

错误是如何解决的?关于如何进行的任何建议?

3 个答案:

答案 0 :(得分:1)

数据库列的类型可能不正确。在我的情况下,我有一个枚举字段,它以字符串形式存储,但我忘记在数据库上下文中添加.hasConversion<string>()

答案 1 :(得分:0)

显然,在某处您尝试将字符串转换为int。问题是你不知道在哪里。

由于您发布了标有实体框架的问题,我认为问题出现在该领域。

如何诊断问题是什么?

在某个地方你有一个派生自DbContext的类,其DBSet属性描述了你的表:

class MyDbContext : DbContext
{
    public DbSet<MyItem> MyItems {get; set;}
    public DbSet<YourItem> YourItems {get; set;}
}

在某个地方,你有一个困难的linq查询会引发你的异常:

using (var myDbContext = new DbContext())
{
    var result = myDbContext.MyItems.SomeDififultLingQuery();
}

其中SomeDifficultLinqQueryWhereSelectGroupByTEnumerable以及“IQueryable”的许多其他扩展名的串联。

要诊断出问题所在,请将DifficultLinqQuery分成较小的步骤,然后检查调试器的每个结果:

IQueryable<MyItem> result1 = myDbContext.MyItems;
var result1List = result1.ToList();

IQueryable<MyItem> result2 = result2.Where(item => item.name = "Trump");
var result2List = result2.ToList();

var result3 = result2.GroupBy(item => item.Address)
var result3List = result3.ToList();

var result4 = result3.Select(item => new
{
    President = item.Name,
    Tweet = ...
};
var result4List = result4.ToList();

现在在调试器中,在第一步停止,并在每一步之后检查结果。某处有一个字符串,您尝试将其转换为int。您的调试器会告诉您何时无法完成此操作。

要将字符串转换为int32,请使用Int32.Parse。如果你的ling-to-sql提供者不支持这个,你必须尽可能长时间地保持你的字符串。在转换使用AsEnumerable()

之前

var resultX = ... //此步骤是最后一个有效的步骤    var resultY = resultX.AsEnumerable()        。选择(item =&gt; new         {             intValue = Int32.Parse(item.StringValue),             ...         }

答案 2 :(得分:0)

感谢您提供非常详细而富有洞察力的回复。使用这些技术,虽然我还不确定为什么,但是能够识别并解决问题。

在我们的设计中 - 使用EF Core 1.0.4 table-per-hierarchy - 我们有一个LegalEntity类。业务和参与者继承自LegalEntity。实体可以拥有许多员工(参与者)。参与者可以拥有许多雇主(LegalEntities)。

要解决问题 - 在上下文类的“OnModelCreating”方法中 - 添加了流利语句:

modelBuilder.Entity()      .HasMany(z =&gt; z.Employees).WithOne()。HasForeignKey(z =&gt; z.EmployerID);

modelBuilder.Entity()      .HasMany(z =&gt; z.Employers).WithOne()。HasForeignKey(z =&gt; z.EmployeeID);

所以,流利的陈述,以及LegalEntity中定义的集合......

public ICollection Employees {get;组; }

...加上参与者中定义的集合:

public ICollection雇主{get;组; }

...导致创建4个外键。

问题现在解决了。不要问我怎么/为什么。

它还解决了以下错误:

无法将类型为“System.Boolean”的对象强制转换为“System.Int32”。