How to get original values of an entity in Entity

2019-01-18 02:41发布

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 ?

6条回答
够拽才男人
2楼-- · 2019-01-18 03:19

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();
    }
查看更多
唯我独甜
3楼-- · 2019-01-18 03:26

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.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-01-18 03:28

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();

Docs https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.103).aspx

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

查看更多
家丑人穷心不美
5楼-- · 2019-01-18 03:33

@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);
查看更多
对你真心纯属浪费
6楼-- · 2019-01-18 03:36

You can access them through ObjectStateEntry

var originalValues = context
         .ObjectStateManager.GetObjectStateEntry(myEntity).OriginalValues;
查看更多
beautiful°
7楼-- · 2019-01-18 03:37

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;
}
查看更多
登录 后发表回答