Problem
I want to save the attributes of a model that have changed when a user edits them. Here’s what I want to do …
- Retrieve edited view model
- Get domain model and map back updated value
- Call the update method on repository
- Get the “old” domain model and compare values of the fields
- Store the changed values (in JSON) into a table
However I am having trouble with step number 4. It seems that the Entity Framework doesn’t want to hit the database again to get the model with the old values. It just returns the same entity I have.
Attempted Solutions
I have tried using the Find() and the SingleOrDefault() methods, but they just return the model I currently have.
Example Code
private string ArchiveChanges(T updatedEntity)
{
//Here is the problem!
//oldEntity is the same as updatedEntity
T oldEntity = DbSet.SingleOrDefault(x => x.ID == updatedEntity.ID);
Dictionary<string, object> changed = new Dictionary<string, object>();
foreach (var propertyInfo in typeof(T).GetProperties())
{
var property = typeof(T).GetProperty(propertyInfo.Name);
//Get the old value and the new value from the models
var newValue = property.GetValue(updatedEntity, null);
var oldValue = property.GetValue(oldEntity, null);
//Check to see if the values are equal
if (!object.Equals(newValue, oldValue))
{
//Values have changed ... log it
changed.Add(propertyInfo.Name, newValue);
}
}
var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
return ser.Serialize(changed);
}
public override void Update(T entityToUpdate)
{
//Do something with this
string json = ArchiveChanges(entityToUpdate);
entityToUpdate.AuditInfo.Updated = DateTime.Now;
entityToUpdate.AuditInfo.UpdatedBy = Thread.CurrentPrincipal.Identity.Name;
base.Update(entityToUpdate);
}
The issue is that Entity Framework cache’s the objects it reads in the DbSet. So when you request the object the second time, it isn’t going to the database because it already has loaded it.
However, the good news is that Entity automatically tracks the original values. See this question for information on how to get them: How to get original values of an entity in Entity Framework?