开发者

NHIbernate: Mapping Audit user

On every object in my DB, I hav开发者_开发问答e audit fields for CreatedBy, CreatedOn, ModifiedOn, and ModifiedBy. the CreatedBy and ModifiedBy map to a User object that I have created to map to my users table. I was originally storing the UserId (Primary key) in those fields and everything mapped fine with a mapping definition of <many-to-one name="CreatedBy" column="CreatedBy" lazy="proxy"></many-to-one>.

However, I want to switch those fields to store the username instead but I can't find how to load the persistent User entity from the non-primary-key field. I've looked into IUserTypes, ICompositeUserType, event listeners, and some other random things, but I can't seem to get anything completely working.

As of right now I've added a CreatedByName and ModifiedByName field that stores the username while the original fields still store the ID (did this when playing around with CompositeUserType), so I have both ID and username that I can utilize if needed.

This seems like something that should be common enough that there should be a solution, but I can't find anything.


You can specify the property-ref attribute in your many-to-one to specify an arbitrary join property.

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


Since auditing is not a business concern, I have found the best way to solve this is to use NHibernate event listeners.

A sample listener might look like this:

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;
        }
    }
}

I log the user and the date the entity was inserted. There is also a preupdate listener. Of course, you'd have to configure the listeners with NHibernate Configuration.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜