How do I implement ChangeTime and ChangeUser columns using NHibernate?

后端 未结 4 1119
你的背包
你的背包 2020-12-05 08:19

I\'m trying to use NHibernate with an existing database. In the data-model there is columns in each table that contains the time and username of the last update made to a ro

相关标签:
4条回答
  • 2020-12-05 08:55

    Mookid's answer is correct although I would like to point out that if one is using S#arp Architecture, the NHib configuration should be set up as follows:

    <hibernate-configuration>
        <session-factory>
        ...
            <event type="pre-update">
                <listener class="MyListener, MyAssembly"/>
            </event>
            <event type="pre-insert">
                <listener class="MyListener, MyAssembly"/>
            </event>
        </session-factory>
    </hibernate-configuration>
    

    The event elements go into the session-factory element.

    0 讨论(0)
  • 2020-12-05 09:01

    You should register a listener to the pre insert and pre update events. You can do it through your configuration like so:

    <hibernate-configuration>
        ...
        <event type="pre-update">
            <listener class="MyListener, MyAssembly"/>
        </event>
        <event type="pre-insert">
            <listener class="MyListener, MyAssembly"/>
        </event>
    </hibernate-configuration>
    

    and then implement a listener - something like this (might not be entirely accurate - written off my memory):

    public class MyListener : IPreUpdateEventListener, IPreInsertEventListener
    {
        public bool OnPreUpdate(PreUpdateEvent evt)
        {
            if (evt.Entity is IHasLastModified)
                UpdateLastModified(evt.State, evt.Persister.PropertyNames);
    
            return false;
        }
    
        public bool OnPreInsert(PreInsertEvent evt)
        {
            if (evt.Entity is IHasLastModified)
                UpdateLastModified(evt.State, evt.Persister.PropertyNames);
    
            return false;
        }
    
        void UpdateLastModified(object[] state, string[] names)
        {
            var index = Array.FindIndex(names, n => n == "LastModified");
    
            state[index] = DateTime.Now;
        }
    }
    

    and do the same thing with the pre update event.

    EDIT: This one takes care of insert as well as update and it seems to work.

    0 讨论(0)
  • 2020-12-05 09:01

    Instead of using LIsteners, you can also use Interceptors: Audit changes using interceptor

    0 讨论(0)
  • 2020-12-05 09:12

    Hey I just had to solve this on a project I am working on, here is my answer

    public interface IDateModified
    {
        DateTime Created { get; set; }
        DateTime Modified { get; set; }
    }
    
    public class CustomDefaultSaveOrUpdateEventListener 
        : DefaultSaveOrUpdateEventListener
    {
        protected override object EntityIsPersistent(SaveOrUpdateEvent evt)
        {
            var entity = evt.Entity as IDateModified;
            if (entity != null)
            {
                    entity.Modified = DateTime.Now;
            }
    
            return base.EntityIsPersistent(evt);
        }
    
        protected override object EntityIsTransient(SaveOrUpdateEvent evt)
        {
            var entity = evt.Entity as IDateModified;
            if (entity != null)
            {
                entity.Created = entity.Modified = DateTime.Now;
            }
    
            return base.EntityIsTransient(evt);
        }
    }
    

    Then in my configuration (I am using Fluent NHibernate to configure my unit tests in code)

    configuration.EventListeners.SaveOrUpdateEventListeners 
    = new ISaveOrUpdateEventListener[]
    {
        new CustomDefaultSaveOrUpdateEventListener() 
    };
    

    AWESOMENESSSSSSSS!

    0 讨论(0)
提交回复
热议问题