Реализация журнала аудита / истории изменений с помощью MVC и Entity Framework

Я создаю журнал изменений / журнал аудита для моего приложения 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);
    }
}
31
задан baron 29 July 2011 в 04:40
поделиться