Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force EF 4.1 Code First to See an Attached entity as Modified

All the examples I've found refer to a class called ObjectContext, which doesn't appear to exist in CTP5. I must stress at this point, CTP5 is my first exposure to the Entity Framework.

I have a disconnected POCO that I have attached to my DbContext. SaveChanges does not pick up the change though, how I tell my context to update that entity?

_context.Users.Attach(user);
// The user has been replaced.
_context.SaveChanges();
// The change is not saved.

What am I doing wrong?

Update 12/01/2011 Might be obvious to most, but as a first time user of EF, it didn't occur to me that attaching an object that was already attached would clear the previous state. This caused me a lot of pain. But I wanted to use the Repository pattern in a very generic way, a way which didn't care if the object was already attached or had been freshly created as the result of ASP.NET MVC binding. So I needed an UpdateUser method, and I've attached it below.

    public User UpdateUser(User user) {
        if (_context.Entry(user).State == EntityState.Detached) {
            _context.Users.Attach(user);
            _context.Entry(user).State = EntityState.Modified;
        }
        return user;
    }

The method obviously assumes that the object exists in the data store in some fashion, it's called UpdateUser after all. If the object is already attached, you will benefit from the object's previous state, which in turn will allow for an optimised update to the DB. However, if the object was not attached, the method forces the whole thing to become dirty.

Seems obvious now, wasn't before. Hope it helps someone.

Rich

like image 606
kim3er Avatar asked Dec 10 '10 22:12

kim3er


People also ask

How does DbContext change state of entity?

This can be achieved in several ways: setting the EntityState for the entity explicitly; using the DbContext. Update method (which is new in EF Core); using the DbContext. Attach method and then "walking the object graph" to set the state of individual properties within the graph explicitly.

How do I change EntityState to entity Framework?

Changing the state of a tracked entity Note that calling Add or Attach for an entity that is already tracked can also be used to change the entity state. For example, calling Attach for an entity that is currently in the Added state will change its state to Unchanged.

What is EntityState in entity Framework?

EF API maintains the state of each entity during its lifetime. Each entity has a state based on the operation performed on it via the context class. The entity state represented by an enum System.


3 Answers

When you Attach an entity, it goes to Unchanged state (it has not been changed since it attached to the context). All you need to is to explicitly change the Entity State to Modified:

_context.Users.Attach(user);
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
_context.SaveChanges();
like image 129
Morteza Manavi Avatar answered Oct 21 '22 20:10

Morteza Manavi


For the sake of completeness, you can access the ObjectContext by casting the DbContext to IObjectContextAdapter:

((IObjectContextAdapter)context).ObjectContext.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);

Morteza's method is much cleaner though and gets my vote.

like image 22
Paul Hiles Avatar answered Oct 21 '22 21:10

Paul Hiles


I believe u do not need to attach the entity before u call modified. simply setting to modified will do the job.

if (_context.Entry(user).State == EntityState.Detached)
{
    _context.Entry(user).State = EntityState.Modified;
}
like image 34
zeeshanhirani Avatar answered Oct 21 '22 22:10

zeeshanhirani