Reputation: 4977
In EF 4.0, if I understand it right, there are two type of values in Entity : current values and original values.
We can set original values by calling ApplyOriginalValues(TEntity) method but how to get original values ?
Upvotes: 25
Views: 36647
Reputation: 101
var originalEntity = (EntityType)context.Entry(editEntity).OriginalValues.ToObject();
Sorry for my english. With this way you can get the original entity values in the form of the object entity with no changes on the edit values.
Example: If you like edit a Person the line in top look like this
var originalPerson = (Person)context.Entry(editPerson).OriginalValues.ToObject();
Upvotes: 10
Reputation: 24
This answer refers to Entity Framework 6. In EF 6 there is an Original value and Current value https://msdn.microsoft.com/en-us/library/gg679512(v=vs.113).aspx After looking and not finding a good answer I came up with the following test function and thought I would post it for others needing to do the same.
private void test()
{
// table has a field Description of type varchar(200)
WDMDBEntities context = new WDMDBEntities();
var query = context.Brands;
List<Brand> records = query.ToList();
if (records.Count > 0)
{
Brand currentRecord = records[0];
currentRecord.Description = "some new text";
string originalValue = null;
switch (context.Entry(currentRecord).State)
{
case System.Data.Entity.EntityState.Added:
originalValue = null;
break;
case System.Data.Entity.EntityState.Deleted:
case System.Data.Entity.EntityState.Detached:
case System.Data.Entity.EntityState.Modified:
case System.Data.Entity.EntityState.Unchanged:
originalValue = context.Entry(currentRecord).Property(u => u.Description).OriginalValue;
break;
}
}
context.Dispose();
}
Upvotes: 0
Reputation: 14079
There are a few versions of Entity Framework in use.
I myself prefer Code First and with that API it's easy as
_context.Entry(Entity).Reload();
The older API's have a Refresh method on the ObjectContext which can help in certain use cases
ObjectContext.Refresh(RefreshMode.StoreWins, Entity);
Docs https://msdn.microsoft.com/en-us/library/bb896255(v=vs.110).aspx
Upvotes: 1
Reputation: 41
I ran into a similar problem and AsNoTracking was not an option for my situation so i came up with something that works well enough for me: first "clone" the entity then do changes.
public T Clone<T>(T entity)
where T : class, new() {
var clone = new T();
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
.Where(a => a.CanRead &&
a.CanWrite &&
a.GetMethod.IsFinal);
foreach (var property in properties) {
property.SetValue(clone, property.GetValue(entity));
}
return clone;
}
and then compare the clone to the changed.
public string GenerateChangeText<T>(T original, T current)
where T : class, new() {
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
.Where(a => a.CanRead &&
a.CanWrite &&
a.GetMethod.IsFinal);
var changes = string.Empty;
foreach (var property in properties) {
var originalValue = property.GetValue(original);
var currentValue = property.GetValue(current);
if (originalValue == null && currentValue == null) continue;
if ((originalValue != null && !originalValue.Equals(currentValue)) ||
(currentValue != null && !currentValue.Equals(originalValue))) {
changes += $" changed {property} from {original ?? "NULL"} to {current ?? "NULL"}.";
}
}
return changes;
}
Upvotes: 2
Reputation: 7220
@Eranga answer is outdated for EF 5. For some reason, EF 5 doesn't work fine when getting original values using an statement like this:
var originalValues = context.Entry(myEntity).OriginalValues;
My working solution uses AsNoTracking()
method from DbSet
, like the example below:
var originalEntity = context.MyEntities.AsNoTracking().FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);
Upvotes: 38
Reputation: 704
This could be refined further to the following:
var originalEntity = context.MyEntities.AsNoTracking()
.FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);
The Where
in the above, good, response is not needed.
Upvotes: 8
Reputation: 32437
You can access them through ObjectStateEntry
var originalValues = context
.ObjectStateManager.GetObjectStateEntry(myEntity).OriginalValues;
Upvotes: 17