Search code examples
asp.netentity-frameworkentity-framework-4repository-pattern

How to de-attach an entity from a Context in Entity Framework?


I use EF 4.1 with Repository and DbContext.. POCO with T4 template. For every Repository I use a separate DbContext.

I need to update an object with has a related property, at the moment I receive this error

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

I suppose my problem is beacuse eventObj and candidate are created from different Repositories.

So i'm trying to solve the problem with this code, with no success.

My question?

  • How do I get rid of this error?
  • Is is possible remove the candidate from its context?

    public void UpdateAddingCandidate(Event eventObj, Candidate candidate){
        Event updatedEvent = new Event();
        Candidate updatedCandidate = new Candidate();
        updatedEvent = eventObj;
        updatedCandidate = candidate;
        updatedEvent.Candidate = updatedCandidate;
        db.Entry(updatedEvent).State = EntityState.Modified;     
    }
    

EDIT

    public void UpdateAddingCandidate(Event eventObj, Candidate candidate)
    {
        /*
        db.Events.AsNoTracking();
        db.Candidates.AsNoTracking();
        */
        db.Entry(eventObj).State = EntityState.Detached;
        db.Entry(candidate).State = EntityState.Detached;

        Event updatedEvent = new Event();
        Candidate updatedCandidate = new Candidate();
        updatedEvent = eventObj;
        updatedCandidate = candidate;
        updatedEvent.Candidate = updatedCandidate;
        db.Entry(updatedEvent).State = EntityState.Detached;
        db.Entry(updatedEvent).State = EntityState.Modified;

    }

Solution

  • This error is indeed thrown when the entity you're trying to update is attached to a different objectcontext than the context you're using to update it. Only one objectcontext can track an entity

    You can detach objects from it's context by calling:

    where context is the context the entity currently is attached to.

    using (var context = new UnicornsContext())
    {
        var unicorn = new Unicorn { Name = "Franky", PrincessId = 1};
        context.Entry(unicorn).State = EntityState.Detached;
        context.SaveChanges();
    }
    

    http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx

    And in your implementation:

    public void UpdateAddingCandidate(Event eventObj, Candidate candidate)
    {
        db.Entry(candidate).State = EntityState.Detached;
        db.SaveChanges();
    
        eventObj.Candidate = candidate;
        db.Entry(eventObj).State = EntityState.Modified;
        db.SaveChanges();
    }