2010-03-16 110 views
4

我是NHibernate的新手,我無法在此類中映射以下關係。同類流利/ NHibernate集合

public class Category : IAuditable 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name{ get; set; } 
    public virtual Category ParentCategory { get; set; } 
    public virtual IList<Category> SubCategories { get; set; } 

    public Category() 
    { 
     this.Name = string.Empty; 
     this.SubCategories = new List<Category>(); 
    } 

} 

類地圖(雖然,這些實際上是猜測)

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Name); 

     References(x => x.ParentCategory) 
      .Nullable() 
      .Not.LazyLoad(); 

     HasMany(x => x.SubCategories) 
      .Cascade.All(); 

    } 
} 

每個類別可以有一個父類,某些類別有許多子類,等等,等等 我可以得到分類正確保存(數據庫中存在正確的子類別和父類別fk),但在加載時,它會將其自身作爲父類別返回。

我使用流利的類映射,但如果有人可以點我在正確的方向只是簡單的NHibernate,將正常工作。

+0

你自動映射或者你定義classmaps?如果你使用的是classmaps,你可以發佈你的映射嗎? – snicker 2010-03-16 20:15:06

+0

好的,我更新了我的班級地圖,但我不確定他們是否有任何接近。 – 2010-03-16 20:21:43

+0

反面之一? – Paco 2010-03-16 21:57:38

回答

2

確定HasMany(x=>x.SubCategories)確實如此,您需要將Inverse()添加到調用鏈中,並且在給定父類別映射的情況下給出它的列名,我假設它是「ParentCategoryId」,當然這也取決於您的約定。

如果你要發佈你的表stucture我可以給你一個完整的解決方案。

+0

感謝Chris,我允許NHibernate爲我創建數據庫結構而不做任何修改。它創建了列Id,Name,ParentCategoryID和CategoryID。最後兩列總是匹配。我會嘗試添加反轉並查看結果。 – 2010-03-17 13:38:51

+0

更新:反轉似乎沒有效果,但結果保持不變,儘管發出的SQL不同。使用Inverse()插入端的SQL似乎更加正確,但子類別仍未正確加載。它看起來像SQL在選擇時沒有使用正確的FK,我猜測它意味着它需要知道列名,正如你所建議的,儘管我不知道如何用Fluent來指定它。 – 2010-03-17 13:57:04

+1

'HasMany(...)。KeyColumn(「ParentCategoryId」)...' – 2010-03-22 14:56:41

4

按照慣例,流利NHibernate會將「Category_Id」看作外鍵列。它不會找出你的「ParentCategoryId」列。除非將自引用列重命名爲「Category_Id」,否則必須澄清父和子關係的列名。

對於無父(絕對父類)類別,其參考欄爲空,這是合理的回報本身作爲家長或空取決於NHibernate的如何處理它,因爲你選擇預先加載。

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Name); 

     References(x => x.ParentCategory) 
      .Column("ParentCategoryId") // Many-To-One : parent 
      .Nullable() 
      .Not.LazyLoad(); 

     HasMany(x => x.SubCategories) 
      .Cascade.All().Inverse().KeyColumn("ParentCategoryId"); //One-To-Many : chidren 

    } 
} 
+0

這個解決方案寫得很好,所以我給你+1。沒有在引用方面指定,nHibernate正在尋找ParentCategory_Id,所以我更新了HasMany以包含關鍵列。無論哪種方式似乎工作得很好,但我喜歡這個專門告訴它的想法。 – 2010-03-30 15:25:01