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

Dav*_*ave 0 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)
Run Code Online (Sandbox Code Playgroud)

我不确定如何排除/解决此错误。检查所有异常设置不会中断错误,也不会提供任何见解(大概是因为它不是我的代码?)。

我正在使用 EntityFrameworkCore.SQLServer 1.0.4。目前无法升级到较新版本,但使用 1.1.1 时可以成功运行。

使用 SQL Server 2016。VS 2017。

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

错误是如何解决的?关于如何进行有什么建议吗?

Ben*_*eer 7

数据库列可能没有适合您的模型字段的正确类型。就我而言,我有一个枚举字段,我将其存储为字符串,但我忘记添加.hasConversion<string>()到我的数据库上下文中。


Har*_*lse 5

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

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

如何诊断问题所在?

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

class MyDbContext : DbContext
{
    public DbSet<MyItem> MyItems {get; set;}
    public DbSet<YourItem> YourItems {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

并且在某个地方您遇到了困难的 linq 查询,该查询引发了异常:

using (var myDbContext = new DbContext())
{
    var result = myDbContext.MyItems.SomeDififultLingQuery();
}
Run Code Online (Sandbox Code Playgroud)

其中是,SomeDifficultLinqQuery的串联,以及和的许多其他扩展。WhereSelectGroupByIEnumerableIQueryable

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

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

IQueryable<MyItem> result2 = result1.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();
Run Code Online (Sandbox Code Playgroud)

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

要将字符串转换为 int32,请使用Int32.Parse

某些 linq-to-sql 提供程序不支持 Int2.Parse。您将看到无法在运行时解析的确切语句,与上面描述的方式相同。如果您的实体框架克隆不支持 Int32.Parse,则必须选择该字符串作为字符串。在转换之前使用AsEnumerable()

var resultX = ... // this step is the last one that works; your number is still a string
var resultY = resultX.AsEnumerable()
    .Select(item => new
    {
        intValue = Int32.Parse(item.StringValue),
        ...
    }
Run Code Online (Sandbox Code Playgroud)