我正在尝试学习 NH(版本 3.2),但在理解某些映射选择时遇到问题。 Scott Findlater 发布了他性感 Loquacious NH 的完整工作骨架 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 关系?这是否表明类别可以属于多个父类别,即任何给定类别(我认为除了根之外)都可以分布在许多其他父类别中?如果是这样,那么从模型本身来看这不是很清楚,因为对我来说,Parent(正如我在类定义中看到的那样)看起来像类别类型的属性,我会像这样映射它。您什么时候会选择此解决方案中的方法?将其映射为一个简单的属性?
2) 当我映射文件时,我应该从谁(或哪个)角度看?在我看来,这是来自您要映射的类的内部。因此,在这种情况下,当我尝试映射 Category 类时,我只关心映射出去的“箭头”,对吗?
3) 创建映射文件的人必须拥有仅通过查看类就可以清楚了解的知识之外的知识。查看 Products 属性是如何映射的(ManyToMany 关系)。从类本身来看,只能清楚类别可能属于许多产品,但类别不知道它可能包含在许多产品中。对于 Product 类来说,这一事实是显而易见的。现在我已经说过,在我看来,当我创建映射文件时,我应该从类的角度来看,然后是模型的角度。
4)一般来说:什么时候使用.Inverse()、.Cascade()和.Lazy()?
5) 使用 ModelMapper 与 ConventionModelMapper 进行映射有何区别?我还没有研究过使用后一种方法的同一项目中包含的文件,但我想知道除了偏好之外,使用一种方法是否比另一种方法有优势。
最佳答案
斯科特决定建立 Ordinary Association(many-to-one)类别与其父(另一个)类别之间的关联。多对一关联使您可以访问属性映射中找不到的功能,例如级联和获取策略。例如,假设您想要删除父级及其所有子级。级联可以帮助您。
如果你有一个协会,你必须考虑协会的双方。例如,假设'A'和'B'之间有双向一对多关联,您需要注意哪一方管理该关系。当您为 'A' 编写映射时,您会考虑 'A' 与 be 的关系,映射 'B' 时反之亦然。强>.
我对你的观点有点不清楚。然而,您似乎描述的是基本的 OOP 对象关系。类可能具有与对象 'B' 存在关系的属性 'A',而 'B' 又可能与 相关“C”。仅通过查看'A'不可能看出它与'C'传递相关。这没有什么问题。
-
4.1 反向:定义双向关系的哪一方管理该关系。
4.2 级联:允许某些操作级联到子关联。 (例如删除)
4.3 Lazy:定义加载集合的策略。 (急切/懒惰)
ConventionalModelMapper 构建在 ModelMapper 之上,并提供便捷的方法和默认映射约定,使按约定进行映射的体验更加轻松。
关于NHibernate 3.2 映射选择、与POV 的关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7883218/