Entity Framework - Why explicitly set entity state to modified?

Entity Framework

Entity Framework Problem Overview


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?

Entity Framework Solutions


Solution 1 - Entity Framework

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).

Solution 2 - Entity Framework

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;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSeeNoWeevilView Question on Stackoverflow
Solution 1 - Entity FrameworkLadislav MrnkaView Answer on Stackoverflow
Solution 2 - Entity FrameworkGert ArnoldView Answer on Stackoverflow