Entity Framework - Why explicitly set entity state to modified?

Solution 1:

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:

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;