2009-11-17 163 views
3

我正在實現一個自定義的EventListener來保存NHibernate中的審計信息。NHibernate EventListeners - 獲取正在保存的實體的屬性的值

我目前正在擴展DefaultSaveOrUpdateEventListener,覆蓋PerformSaveOrUpdate,遍歷每個實體的屬性並將它們保存到別處。

這適用於簡單的屬性,但在級聯保存一對多關係時失敗。

如果我採取以下實體:

[ActiveRecord] 
public class Child 
{ 
    [PrimaryKey(PrimaryKeyType.GuidComb)] 
    public Guid Id { get; set; } 

    [BelongsTo] 
    public Parent Parent { get; set; } 
} 

[ActiveRecord] 
public class Parent 
{ 
    [PrimaryKey(PrimaryKeyType.GuidComb)] 
    public Guid Id { get; set; } 

    [HasMany(Cascade = ManyRelationCascadeEnum.SaveUpdate)] 
    public IList<Child> Children { get; set; } 
} 

然後保存家長帶着孩子:

ActiveRecordMediator<Parent>.Save(new Parent 
{ 
    Children = new List<Child> 
    { 
     new Child() 
    } 
}); 

的孩子將得到正確的父分配給它的時候保存到數據庫但是當我的EventListener被調用時,孩子的'Parent'屬性爲null。

在這種情況下,我怎樣才能獲得實際上將持久化到數據庫的值?

[編輯]我最近一直在尋找通過鉤住級聯,看看當時還保存着什麼,但這似乎非常不可靠,我更願意從中獲取數據NHibernate所以我知道它與數據庫一致。

回答

2

我不知道如何使用ActiveRecord完成此操作,但它與NHibernate保持父/子關係的機制有關。

在NHibernate中保存父級之前保存子級聯是通過設計取決於關係的哪一端被標記爲「inverse = true」,並且子級需要具有「not-null = true」屬性元素(這決定了哪一端擁有的關係)。這將使得兒童管理關係的狀態。

然後你可以簡單地保存孩子,父母會用適當的信息更新。這將生成一個INSERT語句,而不是您現在可能看到的INSERT AND UPDATE。不知道這是否解決了您的問題,但我相信您遇到的問題是圍繞此行爲。您可以在此鏈接閱讀更多內容:

https://www.hibernate.org/hib_docs/nhibernate/html/example-parentchild.html

+0

謝謝 - 我不確定這是否解決了我的實際問題(Child.Parent在我的偵聽器執行時仍然爲空),但至少我理解我的代碼在惡作劇級聯保存的情況下進行修復,並修復了一個bug 。 – 2009-11-27 10:22:32

0

我看到你使用Castle ActiveRecord。我也在試驗它。

它有一些奇怪的地方,因爲在你提供的代碼中,只有當你的東西被保存到數據庫後,Child對象的Parent屬性纔會被設置。在此之前,其值將爲空。 (我不知道這種行爲是否特定於ActiveRecord或NHibernate。)

也許如果您手動指定了Child對象的Parent屬性,它將起作用。

var parent = new Parent(); 
var child = new Child() 
{ 
    Parent = parent 
}; 
parent.Children.Add(child); 

ActiveRecordMediator<Parent>.Save(child); 
ActiveRecordMediator<Parent>.Save(parent); 

也許您保存實體的順序也必須對此事做些什麼。

+0

是的,沒有。它的工作原理,但它的工作原理是因爲NHibernate沒有進行級聯保存 - 開發人員正在這樣做。不幸的是,這意味着禁用級聯保存,這對於體面的ORM非常重要。 (還是)感謝你的建議。 – 2009-11-22 00:39:49

+0

實際上,級聯保存效果很好,但存在一個問題,即一個孩子沒有獲得其父組,直到它被保存。 (或者至少在我上次嘗試時,ActiveRecord中就是這種情況。) 您的事件偵聽器在發生之前收到這些孩子。 – Venemo 2009-11-22 20:10:42

0

我不使用ActiveRecord,我使用NHibernate的替代,所以我會認爲他們處理以同樣的方式(https://www.hibernate.org/hib_docs/nhibernate/html/example-parentchild.html

父子關係,如果你離開的ORM來管理,會發生什麼鏈接到父級(通過在HasMany屬性中設置Inverse = true)?

[ActiveRecord] 
public class Parent 
{ 
    [PrimaryKey(PrimaryKeyType.GuidComb)] 
    public Guid Id { get; set; } 

    [HasMany(Cascade = ManyRelationCascadeEnum.SaveUpdate, Inverse=true)] 
    public IList<Child> Children { get; set; } 
} 
+0

嗨,本。唉,據我所知,這沒有什麼區別。 – 2009-11-24 19:32:52

相關問題