2009-05-21 53 views
4

我正在使用NHibernate拦截器来记录关于更新/插入/删除到我的各种实体的信息。NHibernate Interceptor审计插入对象Id

包含在记录的信息中的是实体类型和修改实体的唯一ID。 NHibernate映射文件中唯一标识为<generator class="identity">

显而易见的问题是,使用IInterceptor.OnSave()记录插入操作时,实体的Id尚未分配。

如何在记录审计信息之前获取插入实体的ID?

(我看着NHibernate的听众PostSave事件,但可以让他们与Spring.net配置工作不被使用,所以我想坚持使用拦截器如果可能的话)

代码:

// object id parameter is null... 
    public override bool OnSave(object entity, object id, object[] state, 
     string[] propertyNames, IType[] types) 
    {    
     AddAuditItem(entity, INSERT); 
     return false;    
    } 

回答

8

我已经解决了这个问题,在OnSave实现期间向我的拦截器类添加了一个列表,该列表中填充了对象。

PostFlush实现中迭代列表,每个元素都作为插入审计。该列表中的对象已被保存在PostFlush()中,因此生成了ID。

这似乎是工作确定,但我会很感激,如果任何潜在的缺陷,指出了:-)

public class AuditInterceptor : EmptyInterceptor 
{  
    // To hold inserted items to be audited after insert has been flushed 
    private IList<object> insertItems = new List<object>(); 

    public override void PostFlush(System.Collections.ICollection entities) 
    {    
     foreach (var entity in insertItems) 
     { 
      AddAuditItem(entity, INSERT); 
     } 
     insertItems.Clear(); 

     base.PostFlush(entities); 
    } 

    public override bool OnSave(object entity, object id, object[] state, 
     string[] propertyNames, IType[] types) 
    {    
     var auditable = entity as IAuditable; 
     if (auditable != null) 
      insertItems.Add(entity); 

     return false;    
    } 
} 
0

尝试OnFlushDirty方法..或者也许PostFlush

编辑:另外,您可以发布您的代码?你不把Id作为OnSave的参数吗?

+0

感谢您的答复。 我试过PostFlush,但我怎么知道ICollection实体参数中的哪些项目是刚插入的项目?如果有一种方法来识别这个,它会工作正常... – TonE 2009-05-21 10:46:44

+0

我相信所有这些......是不是这种情况? – 2009-05-21 11:01:12