The error is
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)
I'm not sure how to troubleshoot/solve this error. Checking-on all Exception Settings doesn't break on the error nor does it provide any insight (presumably because it isn't my code?).
Am using EntityFrameworkCore.SQLServer 1.0.4. Cannot upgrade to newer version at this time but it runs successfully when using 1.1.1.
Using SQL Server 2016. VS 2017.
The problem occurs when invoking the ToList on a complicated IQueryable.
How is the error solved? Any recommendations on how to proceed?
Apparently, somewhere you try to cast a string to an int. The problem is that you don't know where.
Since you are posting this question labeled with entity-framework, I assume the problem is in that realm.
How to diagnose were the problem is?
Somewhere you have a class derived from DbContext
with DBSet
properties describing your tables:
class MyDbContext : DbContext
{
public DbSet<MyItem> MyItems {get; set;}
public DbSet<YourItem> YourItems {get; set;}
}
and somewhere you have your difficult linq query that raises your exception:
using (var myDbContext = new DbContext())
{
var result = myDbContext.MyItems.SomeDififultLingQuery();
}
Where SomeDifficultLinqQuery
is a concatenation of Where
, Select
, GroupBy
and lots of other extensions of IEnumerable
and IQueryable
.
To Diagnose where the problem is, divide your DifficultLinqQuery
into smaller steps, and check in your debugger each result:
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();
Now in the debugger, stop at the first step, and after every step check the result. Somewhere there is a string that you are trying to convert to an int. Your debugger will tell you when this can't be done.
To convert a string to an int32 use Int32.Parse.
Some linq-to-sql providers don't support Int2.Parse. You'll see the exact statement that can't parse at run-time, the same way as described above. If your entity-framework clone does not support Int32.Parse, you'll have to select the string as a string. Just before converting use 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),
...
}
It's likely that a DB column doesn't have the correct type for your model field. In my case I had an enum field which I was storing as a string, and I forgot to add .hasConversion<string>()
in my DB context.
Thank you for your very detailed and insightful response. Using those techniques, the problem was able to be identified and solved although I'm not yet sure why.
In our design - using EF Core 1.0.4 table-per-hierarchy - we have a LegalEntity class. Business and Participant inherit from the LegalEntity. An Entity can have many employees (Participant). A participant can have many employers (LegalEntities).
To solve the problem - in the "OnModelCreating" method of the context class - fluent statements were added:
modelBuilder.Entity<LegalEntity>()
.HasMany(z => z.Employees).WithOne().HasForeignKey(z => z.EmployerID);
modelBuilder.Entity<Participant>()
.HasMany(z => z.Employers).WithOne().HasForeignKey(z => z.EmployeeID);
So, fluent statements, plus the collection defined in the LegalEntity...
public ICollection<RelationshipLegalEntityEmployee> Employees { get; set; }
...Plus the collection defined in the Participant:
public ICollection<RelationshipLegalEntityEmployee> Employers { get; set; }
...result in 4 foreign keys being created.
The problem is now solved. Don't ask me how/why.
It also solved the following error:
Unable to cast object of type 'System.Boolean' to type 'System.Int32'.
User contributions licensed under CC BY-SA 3.0