zzzprojects / EntityFramework-Classic

Entity Framework Classic is a supported version of the latest EF6 codebase. It supports .NET Framework and .NET Core and overcomes some EF limitations by adding tons of must-haves built-in features.
https://entityframework-classic.net
Other
103 stars 27 forks source link

The object cannot be deleted because it was not found in the ObjectStateManager #67

Closed epozsh closed 10 months ago

epozsh commented 11 months ago

Hello getting this error

Unhandled exception. System.InvalidOperationException: The object cannot be deleted because it was not found in the ObjectStateManager.
   at System.Data.Entity.Core.Objects.ObjectContext.DeleteObject(Object entity, EntitySet expectedEntitySet)
   at System.Data.Entity.Core.Objects.ObjectContext.DeleteObject(Object entity)
   at System.Data.Entity.Internal.Linq.InternalSet`1.RemoveRange(IEnumerable entities)
   at System.Data.Entity.DbSet`1.RemoveRange(IEnumerable`1 entities)
   at Program.Main()

while trying use

context.Customers.AttachRange(entitiesToBeDeleted); context.Customers.RemoveRange(entitiesToBeDeleted);

but when using this

foreach(var entityToBeDeleted in entitiesToBeDeleted) { context.Customers.Attach(entityToBeDeleted); context.Customers.Remove(entityToBeDeleted); }

it works as expected

You can check it here

https://dotnetfiddle.net/9j6AqI

Any help?

JonathanMagnan commented 11 months ago

Hello @epozsh ,

After reviewing the Fiddle, there is currently no issue within the library.

The problem is caused because the following part customersIds.Select(cId => new Customer { CustomerID = cId }); is an Enumerable.

This means customer get materialized twice:

This is equivalent of doing the foreach twice which doesn't work either:

foreach(var entityToBeDeleted in entitiesToBeDeleted) {
    context.Customers.Attach(entityToBeDeleted);
}

foreach(var entityToBeDeleted in entitiesToBeDeleted) {
    context.Customers.Remove(entityToBeDeleted);
}

Fiddle: https://dotnetfiddle.net/Wu7USz

To solve it, you can simply to a ToList first:

var entitiesToBeDeleted = customersIds.Select(cId => new Customer { CustomerID = cId });
context.Customers.AttachRange(entitiesToBeDeleted);
context.Customers.RemoveRange(entitiesToBeDeleted);

Let me know if that explains correctly the cause and solution for this issue.

Best Regards,

Jon