NHibernate在保存时自动设置属性

时间:2009-07-20 13:53:23

标签: .net nhibernate persistence

我正在使用DDD和NHibernate来保存我的域对象。在我的数据库中,与实体相关的每个表都有四个用于审计跟踪的额外列(CreatedBy,UpdatedBy,CreatedDate,UpdatedDate)。我使用的存储库模式只允许保存聚合根。当NHibernate尝试在聚合根上保存实体时,我得到一个SQL DateTime错误,因为实体没有设置其审计属性。 NHibernate中有没有办法在保存之前设置对象的属性?

这是一个小例子。我有一个Order对象,它是聚合根。我也有OrderNote对象,它们是订单的子项。当我向Order添加OrderNote然后保存Order时,抛出异常,因为CreatedDate / UpdatedDate设置为DateTime.MinValue,这将导致SQL DateTime溢出。由于这些审计列是持久性的一部分而与问题域无关,因此我不希望订单聚合根在添加注释时设置这些属性。审计列/属性只应由持久性框架而不是域知道。我希望能够告诉NHibernate在保存或更新时设置这些属性。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:11)

拦截器可以这样做:

http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-interceptors(9.10,链接并不总是有效)。

从文档中剪切/粘贴:

public class AuditInterceptor : IInterceptor
{
    ...

    public boolean OnSave(object entity,
                          object id,
                          object[] state,
                          string[] propertyNames,
                          IType[] types)
    {
        if ( entity is IAuditable )
        {
            for ( int i=0; i<propertyNames.Length; i++ )
            {
                if ( "CreateTimestamp" == propertyNames[i] )
                {
                    state[i] = DateTime.Now;
                    return true;
                }
            }
        }
        return false;
    }

}

OnFlushDirty()可用于UpdatedDate。

您将希望每个拥有CreatedDate / UpdatedDate的实体都实现一个接口,以便拦截器可以检查它是否应该行动(在提供的示例中它是IAuditable)。


修改

刚刚注意到第11章:拦截器和事件。您可以从EmptyInterceptor继承,如果您只需要覆盖某些方法,这会使事情变得更容易。

我从未使用过活动。

答案 1 :(得分:1)

您还可以查看NHibernate的版本控制系统,它可以为您提供帮助;)