2011-10-24 113 views
1

我正在努力學習NH(版本3.2),並且在理解一些映射選擇時遇到了問題。 Scott Findlater發佈了性感Loquacious NH here的完整工作框架,關於映射的問題將以他的樣本爲基礎。 這裏是域模型(PIC不是他的樣品的一部分,但這裏包含的清晰度):NHibernate 3.2映射選擇,關係和POV?

enter image description here

他類別類看起來是這樣的:

public class Category : Entity 
    { 
     public Category() 
     { 
      Products = new List<Product>(); 
      SubCategories = new List<Category>(); 
     } 

     public virtual string Name { get; set; } 
     public virtual string Description { get; set; } 
     public virtual Category Parent { get; set; } 
     public virtual IEnumerable<Category> SubCategories { get; set; } 
     public virtual IList<Product> Products { get; set; } 
    } 

和他的映射類是這樣的:

class CategoryMap : ClassMapping<Category> 
    { 
     public CategoryMap() 
     { 
      // ************************************************** 
      // Mapping of Id here will take precedence over the 
      // global conventions configured in the ModelMapper. 
      // ************************************************** 
      //Id(x => x.Id, map => 
      //{ 
      // map.Column("Id"); 
      // map.Generator(Generators.GuidComb); 
      //}); 

      Property(x => x.Name, m => m.Length(450)); 
      Property(x => x.Description, m => m.Length(2000)); 

      Set(x => x.SubCategories, set => 
              { 
               set.Key(k => k.Column("ParentCategoryId")); 
               set.Inverse(true); 
              } , 
             ce => ce.OneToMany()); 

      ManyToOne(x => x.Parent, manyToOne => 
             { 
              manyToOne.Column("ParentCategoryId"); 
              manyToOne.Lazy(LazyRelation.NoLazy); 
              manyToOne.NotNullable(false); 
             }); 


      Set(x => x.Products, set => 
            { 
             set.Key(key => 
             { 
              key.Column("ProductId"); 
              key.ForeignKey("FK_Product_Category_ProductId"); 
             }); 
             set.Table("Product_Category"); 
            }, 
            ce => ce.ManyToMany(m => m.Column("CategoryId"))); 
     } 
    } 

現在,對於問題:

1)爲什麼他選擇將Parent屬性映射/模型化爲ManyToOne關係?這是否表明類別可以屬於多個父類別,即任何給定的類別(除了我認爲的根類別)都可以分散到許多其他父類別中?如果是這樣的話,這個模型本身並不是很清楚,因爲對於我來說,父類(就像我在類定義中看到的那樣)看起來像一個類型屬性,我會像這樣映射它。你什麼時候在這個解決方案v.s.中選擇了方法?將它映射爲一個簡單的屬性?

2)當我映射文件時,誰應該從哪個角度看(或哪個角度)?在我看來,這是來自你想要映射的課程的內部。因此,在這種情況下,當我嘗試映射Category類時,我只關心映射「箭頭」出去,對吧?

3)創建映射文件的人必須具有除了通過查看類才能清楚的知識之外的知識。看看產品屬性如何映射(ManyToMany關係)。從類本身來看,只有類別可以屬於許多產品,但類別不知道它可能包含在許多產品中。這個事實對於產品類是顯而易見的。現在我已經說過,在我看來,當我創建映射文件時,我應該從類和視圖的角度來看待模型。 4)一般來說:你什麼時候使用.Inverse(),.Cascade()和.Lazy()?

5)使用ModelMapper與ConventionModelMapper進行映射的區別是什麼?我沒有研究過使用後一種方法的同一個項目中包含的文件,但我想知道除了偏好之外是否存在使用另一種方法的優點。

回答

2
  1. 斯科特決定設立一個類別及其父(其他)類別之間的Ordinary Association(many-to-one)關聯。通過多對一的關聯,您可以訪問在屬性映射中找不到的功能,例如級聯和提取策略。例如,假設您想要刪除父母及其所有孩子。瀑布可以幫助你。

  2. 如果你有一個關聯,你必須考慮關聯的雙方。例如,假設您在'A''B'之間存在雙向一對多關聯,則需要注意哪一方管理關係。當你爲「A」寫一個映射,您認爲如何「A」映射「B」當涉及到是,反之亦然條款。

  3. 你的觀點對我來說有點不清楚。但是,您似乎要描述的是基本的OOP對象關係。一類可具有屬性「A」這是一個關係到對象「B」「B」反過來可能涉及「C」。僅僅通過查看'A'就不可能知道它與'C'是傳遞性相關的。沒有什麼不妥。

  4. Read the documentation

    4.1反向:定義雙向關係的哪一側管理關係。

    4.2級聯:允許某些操作級聯到兒童協會。 (例如刪除)

    4.3懶惰:定義加載收集的策略。 (熱切/懶惰地)

  5. ConventionalModelMapper建立在ModelMapper的基礎之上,提供了便捷的方法和默認的映射約定,使常規映射體驗更加簡單。

+0

我想那時我有一個問題檢測(當看一個領域模型)當關聯是雙向/單向的。我應該如何考慮產品和類別之間的關聯?通過查看模型,我看到了兩個一對多關聯 - 產品有很多類別和類別都有很多產品。那是不正確的?或者我應該將其視爲一個多對多的關聯? – user981375

1
  • 對於這並不意味着每個類別都有許多一個父類,這意味着許多類別可以在同一個父類來表示每個類別可以有子類別的列表。如果它表達爲一對一,這意味着每個類別只有一個類別,我認爲你不是這個意思。

  • 對於4.Inverse()用於指定關聯的所有者,所以在兒童實體不是關係的所有者或子實體將您可以使用它在一個一對多的關係不對關係負責,它不會對關係負責,所以如果設置爲true,NHibernate不會嘗試插入或更新由連接定義的屬性。

  • Cascade()指定將從父實體級聯到關聯實體的操作。

  • lazy用於延遲加載其他實體引用的實體。

  • 對於2.和3.我不明白你的意思,你是什麼意思,但我認爲當你映射一個實體時,是的,你應該從你正在映射的類的角度來看,並且相同對於關係的另一方來說,當你映射時,它從它的角度看待投入,同時你應該考慮關係的兩個方面。