Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bring back DbContext.Detach() method with an extension method (EF5) [duplicate]

There is no Detach(object entity) on the DbContext in Entity Framework 5.

To detach an entity, the state now needs to be changed. Maybe I am missing something, but this seems much less intuitive and readable than using the Detach method:

context.Entry(myEntity).State = EntityState.Detached;

I am tempted to just create an extension method to bring back the Detach method:

public static void Detach(this MyEntities context, object entity)
{
    context.Entry(entity).State = EntityState.Detached;
}

What is the reason why Microsoft removed the DbContext.Detach() method in EF 5?

like image 241
Dave New Avatar asked May 22 '13 10:05

Dave New


People also ask

How do I detach an EF core entity?

If you want to detach an object that is already attached to the context, set the state to Detached . If you want to load entities from the DB without attaching them at all to the context (no change tracking), use AsNoTracking . @kjbartel : this is the expected behavior, since the entity has no link with the context.

What is Entitystate detached?

An entity is in this state immediately after it has been created and before it is added to the object context. An entity is also in this state after it has been removed from the context by calling the Detach(Object) method or if it is loaded by using a NoTrackingMergeOption.


2 Answers

Removing a Detach method from the (DbContext) API has some logic because Detach doesn't operate on an object graph but it only detaches the single object that you pass into the method. This is different to all other methods that change the object state:

  • Attach attaches the supplied object including all related objects in the object graph of navigation properties
  • Add adds the supplied object including all related objects to the context
  • Remove deletes the supplied object including the related objects that have been configured with cascading delete

On the other hand setting the state manually to Modified, Added or Deleted always only acts on the supplied object, not on the related objects. This is also the case for calling the Detach method of ObjectContext. It is more consequent to detach an object only via setting the state to Detached to be in line with the behaviour of other state changes because like setting any other state it only influences the supplied object without related objects.

DbContext is - among other features - intended to make working with Entity Framework easier. The old Detach method was more confusing and its behaviour is not like many developers expect. (Here and here are two references about this confusion and the complexities involved in detaching an object.) In my opinion it wasn't the wrong step to remove it from the DbContext API.

Well, you can always write you own extension method like you did or access the underlying ObjectContext via the adapter if you really want to have a Detach method.

like image 130
Slauma Avatar answered Oct 06 '22 00:10

Slauma


I've no idea why there is no Detach() method but the DbSet class exposes a method AsNoTracking() to fetch objects that are detached from the DbContext.

Here's some example code from here

using (var context = new UnicornsContext())
{
    // Query for all unicorns without tracking them
    var unicorns1 = context.Unicorns.AsNoTracking();

    // Query for some unitcorns without tracking them
    var unicorns2 = context.Unicorns
        .Where(u => u.Name.EndsWith("ky"))
        .AsNoTracking()
        .ToList();
} 
like image 22
qujck Avatar answered Oct 05 '22 23:10

qujck