Как я могу сделать общее отслеживание изменений на уровне полей и компонентов в NHibernate? - PullRequest
3 голосов
/ 02 октября 2009

В моем приложении у меня есть несколько различных типов сущностей, для которых требуется отслеживание изменений на уровне поля. Я гуглил по этому поводу и могу привести только примеры выполнения простого отслеживания аудита «Дата вставлена» и «Дата обновлена», когда вы просто изменяете поля в сущности, которая уже сохраняется. Мои требования сложнее, потому что:

  1. Мне нужно создать новые сущности, представляющие изменения, а не просто изменить поля в сохраняемой сущности (как, например, в случае с датой вставки, обновлениями даты, которую я нашел)
  2. Мне нужно сохранить эти новые сущности в БД в той же транзакции, обновляя отслеживаемую сущность
  3. Мне нужно отслеживать изменения в коллекциях ValueObjects, прикрепленных к отслеживаемой сущности
  4. Я не хочу писать отдельный код регистрации для каждой отслеживаемой сущности

Пример кода:

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.

1 Ответ

1 голос
/ 02 октября 2009

То, что вы хотите, это использовать сеанс Iinterceptor. Вы можете найти пример использования этого для аудита здесь

Также вы, вероятно, получите больше ответов из списка рассылки NHibernate .

...