Thursday, September 4, 2014

Entity Framework : Update only changed fields instead of all fields

If we follow the Entity Framework's general approach to edit, it would be something similar to this.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "FacilityID, FacilityName, AddressLine1, AddressLine2")] 
Facility facility)
{
  ...
  if( ModelState.IsValid )
  {
    db.Entry(facility).State = EntityState.Modified;
    db.SaveChanges();
    return RedirectToAction("Index");
  }
..
}

The code in the above treats all fields as `Modified` and saves all field data into the database whether the old and new value of each field is the same or different.

However, there are times that we need to update only certain fields, instead of updating all fields data. The above example would update all field data (FacilityName, AddressLine1, AddressLine2), even when only AddressLine1 was changed by user. In order to save only the changed field data into the database, we can try the following approach: compare each field's value between old and new first and perform update only on the ones that are different.
using System.Data.Entity.Infrastructure;
...
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
  [Bind(Include = "FacilityID, FacilityName, AddressLine1, AddressLine2")] 
   Facility facility)
{
  ...
  if( ModelState.IsValid)
  {
    db.Facilities.Attach( facility );
    DbEntityEntry entry = db.Entry( facility );
    foreach( var propertyName in entry.OriginalValues.PropertyNames )
    {
      // Get the old field value from the database.
      var original = entry.GetDatabaseValues().GetValue<object>(propertyName);
      // Get the current value from posted edit page.
      var current = entry.GetCurrentValues.GetValue<object>(propertyName);
      if(!object.Equals(original, current))
      {
        entry.Property( propertyName ).isModified = true;
      }
    }
    db.SaveChanges();
  }
}


Here we first get all property names (field names) and inspect each property's old and new values. Old values are retrieved from the database. New values are ones submitted by user through post.
// Get the old field value from the database.
var original = entry.GetDatabaseValues().GetValue<object>(propertyName); 
// Get the current value from posted edit page.
var current = entry.GetCurrentValues().GetValue<object>(propertyName); 
When the two values of original and current of a property are not equal,
that property will be assigned `IsModifed = true`, and its current value will be saved into the database.

On the other hand, if current field's values exist in the database already, those field values will be skipped while db.SaveChanges() is performed .


No comments: