2011-10-24 145 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.我不明白你的意思,你是什么意思,但我认为当你映射一个实体时,是的,你应该从你正在映射的类的角度来看,并且相同对于关系的另一方来说,当你映射时,它从它的角度看待投入,同时你应该考虑关系的两个方面。