В моем приложении у меня есть несколько различных типов сущностей, для которых требуется отслеживание изменений на уровне поля. Я гуглил по этому поводу и могу привести только примеры выполнения простого отслеживания аудита «Дата вставлена» и «Дата обновлена», когда вы просто изменяете поля в сущности, которая уже сохраняется. Мои требования сложнее, потому что:
- Мне нужно создать новые сущности, представляющие изменения, а не просто изменить поля в сохраняемой сущности (как, например, в случае с датой вставки, обновлениями даты, которую я нашел)
- Мне нужно сохранить эти новые сущности в БД в той же транзакции, обновляя отслеживаемую сущность
- Мне нужно отслеживать изменения в коллекциях ValueObjects, прикрепленных к отслеживаемой сущности
- Я не хочу писать отдельный код регистрации для каждой отслеживаемой сущности
Пример кода:
public interface ITrackChanges {}
{
}
public class Account : ITrackChanges
{
public int Id;
public string AccountNumber;
public string CustomerName;
public string CustomerAddress;
}
public class Computer : ITrackChanges
{
public int Id;
public string AssetTag;
public string SerialNumber;
public IEnumerable<IPAddress> IPAddresses;
}
public class IPAddress : ValueObject
{
public string Address;
}
Всякий раз, когда изменяется любое из значений объекта «Учетная запись» или «Компьютер», или меняется список IP-адресов, связанных с объектом «Компьютер», мне нужно создать и сохранить записи об изменениях сущности:
public class EntityChange
{
public string EntityType;
public string EntityId;
public string PropertyName;
public string OldValue;
public string NewValue;
}
Каждый отслеживаемый объект реализует интерфейс маркера ITrackChanges, и каждый объект значения наследуется от базового класса ValueObject. Объекты значений отображаются как компоненты в NHibernate.
В качестве примера того, что я хочу получить в качестве конечного результата, если я обновлю объект Computer с идентификатором 1 и изменит значение AssetTag с "ABC123" на "ABC124" и изменит список IP-адресов с {" 1.2.3.4 "} до {" 1.2.3.4 "," 1.2.3.5 "}, я должен получить 2 записи EntityChange:
EntityChange #1
{
EntityType = "Computer"
EntityId = 1
PropertyName = "AssetTag"
OldValue = "ABC123"
NewValue = "ABC124"
}
EntityChange #2
{
EntityType = "Computer"
EntityId = 1
PropertyName = "IPAddresses"
OldValue = "1.2.3.4"
NewValue = "1.2.3.4, 1.2.3.5"
}
Есть идеи, как лучше всего это реализовать? Из моего прочтения документов мне кажется, что мне нужно написать перехватчик и / или прослушиватель событий, но я не смог найти никаких примеров, кроме тех, которые просто модифицируют обновляемую сущность. Пример кода определенно приветствуется в любых ответах.
Я ошибаюсь, полагая, что это должно быть чем-то поддерживаемым NHibernate? Мне удалось реализовать это в предыдущем приложении, которое использовало LLBLGen в качестве ORM, но мне впервые пришлось реализовать это в приложении, использующем NHibernate.