Как получить исходные значения сущности в Entity Framework? - PullRequest
19 голосов
/ 15 ноября 2011

В EF 4.0, если я правильно понимаю, в Entity есть два типа значений: текущие значения и исходные значения.
Мы можем установить исходные значения, вызвав метод ApplyOriginalValues ​​(TEntity), но как получить исходные значения?

Ответы [ 7 ]

30 голосов
/ 11 июля 2013

@ Ответ Eranga устарел для EF 5. По какой-то причине EF 5 не работает нормально при получении исходных значений с помощью следующего выражения:

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

В моем рабочем решении используется метод AsNoTracking()от DbSet, как в примере ниже:

var originalEntity = context.MyEntities.AsNoTracking().FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);
14 голосов
/ 15 ноября 2011

Вы можете получить к ним доступ через ObjectStateEntry

var originalValues = context
         .ObjectStateManager.GetObjectStateEntry(myEntity).OriginalValues;
6 голосов
/ 25 июня 2014

Это может быть уточнено далее:

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

Where в вышеприведенном, хорошем, ответ не нужен.

1 голос
/ 26 апреля 2019

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

Извините за мой английский. Таким образом, вы можете получить исходные значения объекта в виде объекта объекта без изменений в значениях редактирования.

Пример: Если вам нравится редактировать персонажа, строка сверху выглядит так

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

1 голос
/ 12 декабря 2016

Существует несколько версий Entity Framework.

Я сам предпочитаю Code First, и с этим API это просто, как

_context.Entry(Entity).Reload();

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

В старых API есть метод Refresh для ObjectContext, который может помочь в определенных случаях использования

ObjectContext.Refresh(RefreshMode.StoreWins, Entity);

Документы https://msdn.microsoft.com/en-us/library/bb896255(v=vs.110).aspx

1 голос
/ 06 декабря 2016

Я столкнулся с подобной проблемой, и 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;
}
0 голосов
/ 12 сентября 2017

Этот ответ относится к Entity Framework 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();
    }
...