Я создаю журнал изменений / журнал аудита для моего приложения MVC, которое использует Entity Framework.
Так, в частности, в методе редактирования public ActionResult Edit (ViewModel vm)
мы находим объект, который пытаемся обновить, а затем используем TryUpdateModel (object)
для транспонирования значений из формы на объект, который мы пытаемся обновить.
Я хочу регистрировать изменение, когда любое поле этого объекта изменяется. Итак, в основном мне нужна копия объекта до его редактирования, а затем сравнение ее после того, как TryUpdateModel (объект)
выполнил свою работу. т.е.
[HttpPost]
public ActionResult Edit(ViewModel vm)
{
//Need to take the copy here
var object = EntityFramework.Object.Single(x=>x.ID = vm.ID);
if (ModelState.IsValid)
{
//Form the un edited view model
var uneditedVM = BuildViewModel(vm.ID); //this line seems to confuse the EntityFramework (BuildViewModel() is used to build the model when originally displaying the form)
//Compare with old view model
WriteChanges(uneditedVM, vm);
...
TryUpdateModel(object);
}
...
}
Но проблема в том, что когда код извлекает «неотредактированную виртуальную машину», это вызывает некоторые неожиданные изменения в EntityFramework - так что TryUpdateModel (object);
вызывает исключение UpdateException
.
Итак, вопрос - в этой ситуации - как мне создать копию объекта
вне EntityFramework для сравнения на предмет истории изменений / аудита, чтобы это не повлияло и не изменило то
EntityFramework вообще
редактировать: Не хочу использовать триггеры. Необходимо зарегистрировать имя пользователя, который это сделал.
edit1: Используя EFv4, не слишком уверен, как переопределить SaveChanges ()
, но это может быть вариант
Этот маршрут, похоже, никуда не ведет , для такого простого требования! Наконец-то мне удалось правильно его переопределить, но теперь я получаю исключение с этим кодом:
public partial class Entities
{
public override int SaveChanges(SaveOptions options)
{
DetectChanges();
var modifiedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
foreach (var entry in modifiedEntities)
{
var modifiedProps = ObjectStateManager.GetObjectStateEntry(entry).GetModifiedProperties(); //This line throws exception The ObjectStateManager does not contain an ObjectStateEntry with a reference to an object of type 'System.Data.Objects.EntityEntry'.
var currentValues = ObjectStateManager.GetObjectStateEntry(entry).CurrentValues;
foreach (var propName in modifiedProps)
{
var newValue = currentValues[propName];
//log changes
}
}
//return base.SaveChanges();
return base.SaveChanges(options);
}
}