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?
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.
EntityState.Added : EntityState.Modified; context.SaveChanges(); } } Note that when you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.
DbSet.Attach() method attaches an entire entity graph to the new context with the Unchanged entity state.
The Entity state represents the state of an entity. An entity is always in any one of the following states. Added: The entity is marked as added. Deleted: The entity is marked as deleted.
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).
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).
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.
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With