NHibernate - как проверить все поля сущности? - PullRequest
9 голосов
/ 17 августа 2011

Я использую NHibernate и ищу решение, которое позволит мне проверять изменения во всех полях сущности. Я хочу иметь возможность создавать таблицу истории для каждого объекта, то есть Users -> UsersHistory, которая будет иметь ту же структуру, что и таблица Users, и дополнительные поля, такие как тип операции (обновление, удаление), идентификатор пользователя, который внес изменения и т. Д. не хочу определять такой класс для каждой сущности. Я ищу что-то вроде History<T> (т.е. History<User>), потому что эти записи не принадлежат моему домену и будут использоваться только для подготовки списка изменений, внесенных в сущность. Я также думаю, что было бы лучше создавать вставки в эти таблицы в коде, чем создавать триггеры SQL. По сути, мне просто нужно создать копию записи в таблице истории при обновлении или удалении, и я хочу, чтобы вставка была сгенерирована NHibernate. Мне также нужно будет читать записи из таблиц истории - как я уже говорил, эти таблицы будут состоять из полей сущностей и некоторых общих полей истории.

Я не могу найти руководство о том, как создать такое решение. Все, что я могу найти, это добавить UserModified, updatedTimestamp и т. Д., Если у меня уже есть такие поля на объекте. Однако мне нужна полная история сущности, а не только информация, которая в последний раз изменила запись.

Заранее спасибо за помощь.

Ответы [ 4 ]

15 голосов
/ 17 августа 2011

Для NHibernate есть замечательный журнал аудита с открытым исходным кодом, который называется nhibernate.envers https://bitbucket.org/RogerKratz/nhibernate.envers, поэтому вам не нужно изобретать велосипед.

Он прозрачно интегрируется в NHibernate, без изменений в модели вашего домена или сопоставлениях.

Это так же просто, как добавление ссылки и вызова:

var enversConf = new FluentConfiguration(); 
enversConf.Audit<User>();
nhConf.IntegrateWithEnvers(enversConf);

, тогда как nhConf является вашим объектом конфигурации NHibernate.

Для каждого изменения в вашем объекте создается новая ревизия, вы можете попросить Envers получить ревизию, вызвав:

var reader = AuditReaderFactory.Get(session);
var userInRevOne = reader.Find<User>(user.Id, 1);

или перечислить все ревизии и т. Д. Сами данные ревизии можно дополнить именем пользователя, идентификатором пользователя, меткой времени и т. Д. (Все, что вы можете придумать).

EDIT: И это доступно в NuGet: http://nuget.org/packages/NHibernate.Envers

5 голосов
/ 17 августа 2011

Я думаю, что лучшим решением является использование прослушивателей событий:

http://darrell.mozingo.net/2009/08/31/auditing-with-nhibernate-listeners/

Я написал нечто похожее на выше (измененное после нахождения этого блога), за исключением того, что я сохранил результат в XML.

например:

public void OnPostUpdate(PostUpdateEvent updateEvent)
{
    if (updateEvent.Entity is AuditItem)
        return;

    var dirtyFieldIndexes = updateEvent.Persister.FindDirty(updateEvent.State, updateEvent.OldState, updateEvent.Entity, updateEvent.Session);

    var data = new XElement("AuditedData");

    foreach (var dirtyFieldIndex in dirtyFieldIndexes)
    {
        var oldValue = GetStringValueFromStateArray(updateEvent.OldState, dirtyFieldIndex);
        var newValue = GetStringValueFromStateArray(updateEvent.State, dirtyFieldIndex);

        if (oldValue == newValue)
        {
            continue;
        }

        data.Add(new XElement("Item",
                              new XAttribute("Property", updateEvent.Persister.PropertyNames[dirtyFieldIndex]),
                              new XElement("OldValue", oldValue),
                              new XElement("NewValue", newValue)
                             ));
    }

    AuditService.Record(data, updateEvent.Entity, AuditType.Update);
}

Служба аудита просто строит и добавляет некоторые дополнительные данные, такие как IP-адрес, Пользователь (если есть), обновление системы / службы или действия через веб-сайт или пользователя и т. Д.

Затем в моей БД я храню XML как:

<AuditedData>
  <Item Property="Awesomeness">
    <OldValue>above average</OldValue>
    <NewValue>godly</NewValue>
  </Item>
  <Item Property="Name">
    <OldValue>Phill</OldValue>
    <NewValue>Phillip</NewValue>
  </Item>
</AuditedData>

У меня также есть слушатели Вставить / Удалить.

0 голосов
/ 17 августа 2011

Вот полный пример того, как это сделать: http://www.shawnduggan.com/?p=89.

Также рассматривается в этом сообщении: Аудит журнала nhibernate

0 голосов
/ 17 августа 2011

То, что вы ищете, - это прослушиватели событий (к сожалению, я не могу связать их с соответствующими документами, потому что nhforge.org wiki испытывает NRE ...).

Проверка Комплексный аудит NHibernate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...