如何在Entity Framework中获取实体的原始值?

时间:2011-11-15 09:17:34

标签: entity-framework-4 entity

在EF 4.0中,如果我理解正确,实体中有两种类型的值:当前值和原始值。
我们可以通过调用ApplyOriginalValues(TEntity)方法但是如何获取原始值来设置原始值?

7 个答案:

答案 0 :(得分:30)

对于EF 5,@ Eranga答案已经过时。出于某种原因,使用如下语句获取原始值时,EF 5无法正常工作:

var originalValues = context.Entry(myEntity).OriginalValues;

我的工作解决方案使用AsNoTracking()中的DbSet方法,如下例所示:

var originalEntity = context.MyEntities.AsNoTracking().FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);

答案 1 :(得分:14)

您可以通过ObjectStateEntry

访问它们
var originalValues = context
         .ObjectStateManager.GetObjectStateEntry(myEntity).OriginalValues;

答案 2 :(得分:6)

这可以进一步细化到以下内容:

var originalEntity = context.MyEntities.AsNoTracking()
         .FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);

上面的Where,良好的响应是不需要的。

答案 3 :(得分:1)

我遇到了类似的问题而且AsNoTracking不适合我的情况所以我想出了一些对我来说运作得很好的东西:首先"克隆"然后,实体会做出改变。

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;
}

然后将克隆与更改后的内容进行比较。

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;
}

答案 4 :(得分:1)

正在使用几个版本的Entity Framework。

我自己更喜欢Code First,而使用该API则很容易

_context.Entry(Entity).Reload();

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

较旧的API在ObjectContext上有一个Refresh方法,可以在某些用例中提供帮助

ObjectContext.Refresh(RefreshMode.StoreWins, Entity);

文档https://msdn.microsoft.com/en-us/library/bb896255(v=vs.110).aspx

答案 5 :(得分:1)

var originalEntity =(EntityType)context.Entry(editEntity).OriginalValues.ToObject();

对不起,我的英语。 这样,您可以以对象实体的形式获取原始实体值,而无需更改编辑值。

示例: 如果您喜欢编辑人员,则顶部的行将如下所示:

var originalPerson =(Person)context.Entry(editPerson).OriginalValues.ToObject();

答案 6 :(得分:0)

这个答案指的是实体框架6.在EF 6中有一个原始值和当前值https://msdn.microsoft.com/en-us/library/gg679512(v=vs.113).aspx在查看并没有找到一个好的答案后,我想出了以下测试功能,并认为我会发布它其他人也需要这样做。

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