2009-05-21 107 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