System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Int32'

0

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?

entity-framework
asked on Stack Overflow Jun 13, 2017 by Dave • edited Jun 13, 2017 by Grr

3 Answers

2

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),
        ...
    }
answered on Stack Overflow Jun 13, 2017 by Harald Coppoolse • edited May 18, 2020 by Harald Coppoolse
0

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() .HasMany(z => z.Employees).WithOne().HasForeignKey(z => z.EmployerID);

modelBuilder.Entity() .HasMany(z => z.Employers).WithOne().HasForeignKey(z => z.EmployeeID);

So, fluent statements, plus the collection defined in the LegalEntity...

public ICollection Employees { get; set; }

...Plus the collection defined in the Participant:

public ICollection 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'.

answered on Stack Overflow Jun 14, 2017 by Dave
0

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.

answered on Stack Overflow May 18, 2020 by Benjineer

User contributions licensed under CC BY-SA 3.0