2013-05-25 41 views
0

我將Fluent Nhibernate與自動映射結合使用,並且由於我當前的繼承問題而設置雙向HasMany關係時出現問題。我的代碼流暢的NHibernate HasMany與同一超類的不同子類型的關係

我的簡化版本看起來像這樣

public abstract class BaseClass 
{ 
    public BaseClass Parent { get; set; } 
} 

public class ClassA : BaseClass 
{ 
    public IList<ClassB> BChilds { get; protected set; } 
    public IList<ClassC> CChilds { get; protected set; } 
} 

public class ClassB : BaseClass 
{ 
    public IList<ClassD> DChilds { get; protected set; } 
} 

public class ClassC : BaseClass 
{ 
} 

public class ClassD : BaseClass 
{ 
} 

每個類都可以有一個父有的家長可以有兩種類型的孩子的。 I'm使用表每類型繼承其導致表

  • 「BaseClass的」
  • 「ClassA的」
  • 「ClassB的」
  • 「ClassC」
  • 「D類」

爲了得到一個有效的雙向映射我做了以下覆蓋 (來自ClassA的一個例子)

mapping.HasMany<BaseType>(x => x.BChilds).KeyColumn("Parent_Id"); 
mapping.HasMany<BaseType>(x => x.CChilds).KeyColumn("Parent_Id"); 

這對於只有一種類型的子類的類很有效,但具有兩種子類型的ClassA將在每個列表中獲得BaseType的所有子類型,這些子類型最終將以異常結束。我看過兩種不同的解決方法,但他們都沒有足夠的感覺,我真的相信有更好的解決方法。

解決方法1:指向HasMany映射中的具體子類型。 (更新更多資訊)

mapping.HasMany<ClassB>(x => x.BChilds).KeyColumns("Parent_Id"); 

(BASETYPE與ClassB的替換)有了這個映射的NHibernate會在某些情況下,看在ClassB的表名爲PARENT_ID列,顯然沒有這樣的列,因爲它屬於BaseClass表。只有在ClassA選擇期間添加基於BChild的語句時纔會出現此問題。 e.g加載ClassA的則調用ClassA.BChilds的實體似乎工作,但做一個查詢(使用NhibernateLinq)類似

Query<ClassA>().Where(c => c.BChilds.Count == 0) 

錯誤的表將被使用。因此,我必須在該表中手動創建一個具有相同名稱的新列並複製所有值。它有效,但風險很大,而且不靈活。

解決方法2:向BaseClass添加一列,告訴具體類型並向HasMany映射添加where語句。

(我更新後workaround1 I'm不再知道這可能是一個可行的解決方案)

通過添加一列,他們一樣it's使用表每個層次結構的繼承與完成時discriminatorValue。即BaseType表會得到一個新的列,其值爲ClassA,ClassB ... Tho給出了NHibernate如何很好地處理整體繼承以及通過閱讀NHibernate手冊,我認爲鑑別器不應該被需要在每個表中使用場景,看起來像Nhibernate已經做了硬件,應該能夠以一種乾淨的方式照顧到這一點,而無需添加新的列,只是不知道如何。

回答

0

什麼是您的基類映射和您的子類映射是什麼樣的? 你應該能夠做到

mapping.HasMany(x => x.BChilds); 

並用正確的映射,你不應該有問題。 如果它的功能NHibernate,考慮使用自動映射所以我不具有超越提到覆蓋任何真正classMaps

UseUnionSubclassForInheritanceMapping(); 
+0

I'm。 'mapping.HasMany(x => x.BChilds);應該是相同的as' 'mapping.HasMany (X => x.BChilds);' 即相同我的解決方法1(其正在使用錯誤的表) 我會看UseUnionSubclassForInheritanceMapping(); – user2420187

+0

查看UseUnionSubclassForInheritanceMapping我的第一個理解是,你會使用或鑑別技術。我無法通過將其添加到我的映射中來看到任何不同,因此我懷疑這是已經在使用的策略。我將詳細闡述我的問題,關於何時出現錯誤表的問題,以及在所有測試來回之後滑出我的腦海。基本上,如果用上面的映射加載一個ClassA對象,然後調用ClassA.BChilds會給出正確的結果,但是NhibernateLinq查詢將使用錯誤的表。 – user2420187

相關問題