简体   繁体   中英

Why am I getting an InvalidCastException when updating entity?

I am developing an MVC project which is a small part of a big system. We have an ORM service which is created with NTier Entity Framework (it is essentially .Net EF with N Tier support) and this ORM supplies us DataContext. I am struggling with a problem for almost two days and googling is a no go. Here is my update action:

IzinTalep original = DataContext.IzinTalep.AsQueryable()
    .Where(p => p.idtIzinTalep == id).FirstOrDefault();

// [...] some changes to entity are made

original.IsApproved = false;//this is the only boolean in the entity

// [...] some other changes to entity

try
{
    DataContext.IzinTalep.Add(original);
    DataContext.SaveChanges();//the InvalidCastException is thrown here
}
catch (Exception e)
{ }

The exception details say:

Unable to cast object of type 'System.Boolean' to type 'NTier.Common.Domain.Model.Entity'.

If I comment out the IsApproved line, everything works like a charm. Unfortunately, this change to the IsApproved is utterly significant and i have to make it possible.

It's not your fault. The reason was an issue in the n-tier entity framework that has been resoved now with release 1.4

To fix the issue in an existing solution simply update the 'NTierEntityFramework.Common' nuget package. You can do so eg using the Package Manager Console updating all packages in use:

PM> Set-ExecutionPolicy Unrestricted -Scope Process

PM> Update-Package

If this is what I think this is, then this is what was happening to me

I have a poco object (eg Car) I have a Database that has a Car table My poco matches the properties of the database exactly.

My EF model was generated from the database and then I had a nice EF datacontext

The problem being that when I ask my datacontext for a Car it gave me a different type of Car object. Essentially I had a Car class (mine) and a DataContext.Car type (the generated code from the model)

So I had a few options here

1) Create a utility function (I called it MapCar) that would take in a Car and return a DataContext.Car (and another that did the opposite)

eg

Public DataContext.Car MapCar(Car car)
{
     Return new DataContext.Car
     {
         Id = car.Id,
         Make = car.Make,
         etc etc
     };
}


Public Car MapCar(DataContext.Car efCar)
{
     Return new Car
     {
         Id = efCar.Id,
         Make = efCar.Make,
         etc etc
     };
}

2) Similar to #1 above and but us the AutoMapper library

3) Use Linq to do the work for you

var myCar = DataContext.Cars.AsQueryable()
.Where(p => p.Id == id).FirstOrDefault()
.Select(c => new Car {Id=c.Id,Make=c.Make etc etc} );

This is an old problem of NTier Entity Framework which is fixed in the last version. If you want to use the old version you should done following: In Model folder at NTier.Common.Domain package, change 250th line of ChangeSetExtensions.cs to "as Entity" instead of using typecast as "(Entity)".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM