2008-10-29 73 views
0

我正在使用Castle ActiveRecord,但這個問題也適用於NHibernate,因爲與NHibernate一起工作的解決方案應該可以用於ActiveRecord。不管怎麼說,我有一個潛在的表結構是這樣的:NHibernate的/ ActiveRecord的 - 任何方式只映射到外鍵列?

表A -hasMany->表B

我有相應的對象EntityA和EntityB。 EntityA擁有一個EntityB對象的IList。這部分工作正常。現在,我希望EntityB擁有某種對EntityA的引用。我知道我可以使用EntityB的屬於關聯屬性給它一個實際參考回滿EntityA類型,如:

[BelongsTo("tableAid")] 
public EntityA Parent { get; set; } 

但我真的很想做的是:

[BelongsTo("tableAid")] 
public int ParentId { get; set; } 

所以,EntityB將只存儲父對象的ID,而不是對實際對象的引用。這是一個微不足道的例子,但我有充分的理由希望採用這種方法。在我正在處理的應用程序中,我們有一些顯示特定類似EntityB的對象的頁面,我們希望這些頁面能夠包含鏈接(如超鏈接)到相應的父頁面。我們可以通過使用上面的第一種方法來做到這一點,但這需要在我真正需要的是ID時加載整個EntityA對象。這不是一個大問題,但它看起來很浪費。我知道我可以使用延遲加載,但同樣,這似乎更像是一個黑客,我...

我曾嘗試與標記的[屬性]外鍵的屬性,像這樣:

[Property] 
public int ParentId { get; set; } 

這種方法的問題是當您在新的對象樹上執行EntityA.SaveAndFlush()時,EntityB.ParentId保持爲空。正確的值被寫入到數據庫中,我可以通過EntityA.Refresh()強制將值返回到EntityB.ParentId中,但是再次,這看起來有點像黑客。

回答

2

懶惰加載正是你想要的 - 它也不是黑客,它是一個經過良好測試和烘焙的NHIbernate的一部分,當性能調整任何實質的NHibernate應用程序時,它是一個重要的工具。

如果您將您的「父」EntityA標記爲延遲加載,則引用EntityB.Parent.Id根本不會加載EntityA(因爲後臺NHIbernate在加載EntityB時已經加載了EntityA的id) - 因此讓您設置您的鏈接而不會導致性能損失。

0

就在:

[Property] public int ParentId { get; set; } 

...假設ParentId是實際的列名。

其他評論。

首先,您應該考慮延遲加載多對一的屬性。如果你急切地加載它們,你必須意識到可能的負載級聯,這可能會導致嚴重的性能下降。要做到這一點,您必須將所有懶惰加載類的公共成員標記爲虛擬。

其次,請注意,只要您有一個一對多的關聯關係並且沒有從孩子回到父母的對應關係,就必須在數據庫中使FK爲空。這是因爲當NH創建新的子項目時,它會將其插入到父ID爲null的位置,然後在第二步中更新它。

+0

感謝您的建議。我實際上已經嘗試過這種方法,但我忘了在問題中列出它。它主要工作,但不完美。 :( – 2008-10-29 21:18:30