В EF 4.0, если я правильно понимаю, в Entity есть два типа значений: текущие значения и исходные значения.
Мы можем установить исходные значения, вызвав метод ApplyOriginalValues (TEntity), но как получить исходные значения?
Как получить исходные значения объекта в Entity Framework?
Ответ 1
Вы можете получить к ним доступ через ObjectStateEntry
var originalValues = context
.ObjectStateManager.GetObjectStateEntry(myEntity).OriginalValues;
Ответ 2
@Ответ Eranga устарел для EF 5. По какой-то причине EF 5 не работает нормально при получении исходных значений с помощью инструкции вроде этого:
var originalValues = context.Entry(myEntity).OriginalValues;
В моем рабочем решении используется метод AsNoTracking()
из DbSet
, как показано ниже:
var originalEntity = context.MyEntities.AsNoTracking().FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);
Ответ 3
Это может быть уточнено далее:
var originalEntity = context.MyEntities.AsNoTracking()
.FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID);
Where
в приведенном выше, хороший ответ не нужен.
Ответ 4
У меня возникла аналогичная проблема, и 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;
}
Ответ 5
Используется несколько версий Entity Framework.
Я сам предпочитаю Code First и с этим API легко, как
_context.Entry(Entity).Reload();
У более старого API есть метод Refresh объекта ObjectContext, который может помочь в определенных случаях использования
ObjectContext.Refresh(RefreshMode.StoreWins, Entity);
Docs https://msdn.microsoft.com/en-us/library/bb896255(v=vs.110).aspx
Ответ 6
Этот ответ относится к 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();
}
Ответ 7
var originalEntity = (EntityType) context.Entry(editEntity).OriginalValues.ToObject();
Извините за мой английский. Таким образом, вы можете получить исходные значения сущности в форме сущности объекта без изменений значений редактирования.
Пример: если вам нравится редактировать персонажа, строка сверху выглядит так
var originalPerson = (Person) context.Entry(editPerson).OriginalValues.ToObject();