NHIbernate: Пользователь Mapping Audit - PullRequest
1 голос
/ 22 марта 2011

Для каждого объекта в моей БД у меня есть поля аудита для CreatedBy, CreatedOn, ModifiedOn и ModifiedBy. CreatedBy и ModifiedBy сопоставляются с объектом User, который я создал, для сопоставления с таблицей пользователей. Первоначально я сохранял UserId (первичный ключ) в этих полях, и все отображалось нормально с определением сопоставления <many-to-one name="CreatedBy" column="CreatedBy" lazy="proxy"></many-to-one>.

Однако я хочу переключить эти поля для хранения имени пользователя, но не могу найти, как загрузить постоянную сущность пользователя из поля, не являющегося первичным ключом. Я изучил IUserTypes, ICompositeUserType, прослушиватели событий и некоторые другие случайные вещи, но, похоже, я не могу заставить что-либо работать полностью.

На данный момент я добавил поля CreatedByName и ModifiedByName, в которых хранится имя пользователя, в то время как в исходных полях все еще хранится идентификатор (сделал это при игре с CompositeUserType), поэтому у меня есть и идентификатор, и имя пользователя, которое я могу использовать, если необходимо.

Это похоже на то, что должно быть достаточно распространенным, чтобы было решение, но я ничего не могу найти.

Ответы [ 2 ]

1 голос
/ 22 марта 2011

Вы можете указать атрибут property-ref в вашем many-to-one, чтобы указать произвольное свойство соединения.

http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-manytoone

0 голосов
/ 22 марта 2011

Поскольку аудит не касается бизнеса, я нашел лучший способ решить эту проблему - использовать прослушиватели событий NHibernate.

Пример слушателя может выглядеть так:

namespace ADT.Data.Repositories.NHibernate.EventListeners
{


    public class PreInsertEventListener : IPreInsertEventListener
    {


        public bool OnPreInsert(PreInsertEvent @event)
        {
            var audit = @event.Entity as IHaveAuditInformation;
            if (audit == null)
                return false;

            var time = DateTime.Now;
            var user = Security.GetLoggedInUser();

            Set(@event.Persister, @event.State, "LogDate", time);
            Set(@event.Persister, @event.State, "User", user);

            audit.LogDate = time;
            audit.User = user;

            return false;
        }



        private void Set(IEntityPersister persister, object[] state, string propertyName, object value)
        {
            var index = Array.IndexOf(persister.PropertyNames, propertyName);
            if (index == -1)
                return;
            state[index] = value;
        }
    }
}

Я регистрирую пользователя и дату, когда объект был вставлен. Есть также слушатель preupdate. Конечно, вам нужно настроить слушателей с помощью NHibernate Configuration.

...