2009-02-15 86 views
14

我想用现有的数据库NHibernate。在数据模型中,每个表中的列都包含最后一次更新行的时间和用户名。我如何使用NHibernate做到这一点?如何使用NHibernate实现ChangeTime和ChangeUser列?

我试图执行一个拦截器之前被使用IInterceptor.OnSave方法保存的设置ChangeTime和ChangeUser中的实体。这不起作用,因为即使没有修改其他属性,设置这些属性也会触发对该行的更新。

,如果有任何方式告诉NHibernate的排除ChangeTime和ChangeUser性能那么它就是它的肮脏检查它可以工作。但我还没有找到任何方法来完成这一点。

感谢您的任何帮助。

回答

14

您应该注册一个监听器,前置插入和预更新事件。你可以像这样做,通过你的配置:

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

,然后实现一个监听器 - 这样的事情(也许不完全准确 - 注销我的记忆):

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

,做同样的事前更新事件。

编辑:这一个负责插入以及更新和它似乎工作。

+0

谢谢!真的很好的答案,帮了我很多。 此方法不会修改实体的属性,只会修改写入数据库的内容。但是同时设置实体的属性似乎没有问题。 – 2009-02-16 12:40:51

+3

有关此确切问题的更完整解决方案,请参阅http://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx – mookid8000 2009-04-29 14:42:14

1

Mookid的答案是正确的,虽然我想指出的是,如果一个人可以通过对S#ARP架构,NHib配置应设置如下:

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

事件元素进入会话级工厂元素。

5

嘿,我刚刚解决这个一个项目我的工作,这是我的答案

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); 
    } 
} 
在我的配置

然后(我用流利的NHibernate的配置代码我的单元测试)

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

AWESOMENESSSSSSSS!

相关问题