Я должен был сделать это несколько лет назад и для системы управления персоналом. Я сделал это, когда все мои «поля» реализовали шаблон (универсальный):
Вот пример шаблона, который я сделал урезанным:
class DataField<T>
{
public T Current { get; set; }
public T Original { get; set; }
// stores the field name as a nice textual readable representation.
// would default to property name if not defined.
public string FieldName { get; set; }
public bool Modified
{
get { return !(Current.Equals(Original));
}
public DataField(T value)
{
Original = Current = value;
}
public DataField(T value, T fieldName)
{
Original = Current = value;
FieldName = fieldName;
}
}
Интересная часть, которая упростила аудит, заключалась в том, что каждый объект мог создавать свой собственный журнал аудита. Я мог бы взять любой объект, который мог бы иметь х число этих «полей», и вызвать GetAudit, и он вернул бы мне объект аудита со всеми изменениями в классе, показывающими имя поля, старое значение, новое значение и т. Д. Каждый DataField реализует метод для возврата объекта аудита. Для строк, double, ints и т. Д. Он был в значительной степени запечен, но если вы использовали пользовательские объекты, вы могли бы написать реализацию аудита для них, которая просто должна была возвращать объект Audit.
Таким образом, в типичной форме в конце я буду хранить все данные в одном объекте, который имеет все эти типы полей. Затем я сделал бы обновление и вызвал бы метод GetAudit, который также был бы записан в таблицу аудита.
Я легко могу сказать, изменилось ли что-нибудь в форме, даже если им пришлось пройти через несколько страниц и т. Д.
Отменить операции было очень легко на поле за полем, за разделом или за весь уровень объекта.
Немного запутано в точных деталях, так как я долгое время не касался кода, но в этом была его суть. Надеюсь, это поможет.