Why set entity state to changed explicitly in Entity Framework?

entity-framework

Question

The official documentation says to modify an entity I retrieve a DbEntityEntry object and either work with the property functions or I set its state to modified. It uses the following example

Department dpt = context.Departments.FirstOrDefault();
DbEntityEntry entry = context.Entry(dpt);
entry.State = EntityState.Modified;

I don't understand the purpose of the 2nd and 3rd statement. If I ask the framework for an entity like the 1st statement does and then modify the POCO as in

dpt.Name = "Blah"

If I then ask EF to SaveChanges(), the entity has a status of MODIFIED (I'm guessing via snapshot tracking, this isn't a proxy) and the changes are persisted without the need to manually set the state. Am I missing something here?

1
49
8/18/2011 12:27:28 PM

Accepted Answer

In your scenario you indeed don't have to set the state. It is purpose of change tracking to find that you have changed a value on attached entity and put it to modified state. Setting state manually is important in case of detached entities (entities loaded without change tracking or created outside of the current context).

47
8/18/2011 10:59:54 AM

Popular Answer

As said, in a scenario with disconnected entities it can be useful to set an entity's state to Modified. It saves a roundtrip to the database if you just attach the disconnected entity, as opposed to fetching the entity from the database and modifying and saving it.

But there can be very good reasons not to set the state to Modified (and I'm sure Ladislav was aware of this, but still I'd like to point them out here).

  1. All fields in the record will be updated, not only the changes. There are many systems in which updates are audited. Updating all fields will either cause large amounts of clutter or require the auditing mechanism to filter out false changes.

  2. Optimistic concurrency. Since all fields are updated, this may cause more conflicts than necessary. If two users update the same records concurrently but not the same fields, there need not be a conflict. But if they always update all fields, the last user will always try to write stale data. This will at best cause an optimistic concurrency exception or in the worst case data loss.

  3. Useless updates. The entity is marked as modified, no matter what. Unchanged entities will also fire an update. This may easily occur if edit windows can be opened to see details and closed by OK.

So it's a fine balance. Reduce roundtrips or reduce redundancy.

Anyway, an alternative to setting the state to Modified is (using DbContext API):

void UpdateDepartment(Department department)
{
    var dpt = context.Departments.Find(department.Id);
    context.Entry(dpt).CurrentValues.SetValues(department);
    context.SaveChanges();
}

CurrentValues.SetValues marks individual properties as Modified.

Or attach a disconnected entity and mark individual properties as Modified manually:

context.Entry(dpt).State = System.Data.Entity.EntityState.Unchanged;
context.Entry(dpt).Property(d => d.Name).IsModified = true;


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow