一对多映射.NHibernate
本文关键字:NHibernate 映射 一对多 | 更新日期: 2023-09-27 18:10:10
我正在看《NHibernate 3初学者指南》这本书,发现了一个有趣的提示:
在实际的库存应用程序中,您可能希望避免将Products集合放到Category实体上一个类别可能有数百个,如果不是数千个的话相关的产品。加载整个庞大的产品集合对于一个给定的类别是不明智的,并且会导致申请响应时间不理想。
Tip紧随一对多关系建立的例子之后。实体分别为Product
和Category
。这个例子非常简单:
public class Category : Entity // Entity probably contains an `Id` property
{
private List<Products> products;
public String CategoryName { get; set; }
public String Description { get; set; }
public IEnumerable<Product> Products { get { return products; } }
}
public class Product : Entity
{
public Decimal UnitPrice { get; set; }
public String ProductName { get; set; }
public Category Category { get; set; }
}
那么一对多关系的现实例子是什么呢?
仅仅将Category
作为String
属性放入产品实体中就足够了吗?
这个想法是,如果您完全避免使用IList属性,您仍然可以获得一个类别的产品,例如如下:
var products = session.QueryOver<Product>().Where(p => p.Category == someCategory).List();
但你现在有可能做分页,过滤,获得顶级产品等:
var product = session.QueryOver<Product>().Where(p => p.Category == someCategory).OrderBy(p => p.Relevance).Take(1).SingleOrDefault();
,如果它是一个简单的IList属性,则没有。一般来说(以我的经验),双向关联越少,查询粒度就越好。此外,它还减少了您在保存时的复杂性。
您可能想看看Nhibernate的lazy属性。它允许你不加载该属性,除非我们明确要求它。
Nhibernate懒惰
让我们问不同的问题:如果您的应用程序应该在树视图控件中显示类别,在展开类别节点时将列出所有产品,该怎么办?当你想展示所有的产品时,除了……实际查询数据库并加载所有产品
这实际上是非常常见的现实生活场景,最简单的方法之一确实是简单地使用Category.Products
属性。当然,拥有这样的属性并没有错,但真正的问题是您应该如何管理这些对象。
幸运的是,你不需要用单一类别拉所有的产品。可以将Category.Products
标记为惰性加载(与急切加载相反,可以在这里找到更多信息)。这意味着,加载类别不会查询其产品的数据库。相反,NHibernate将为Products
创建代理对象,可以稍后初始化-当它们实际需要时(想想用户扩展类别节点)。
我来回答你的问题…
如果单个产品绑定到恰好一个类别,那么它就是一个很好的现实生活中的一对多关系示例。但是,如果产品可以用一个以上的类别来描述,那么它就是多对多关系。
我认为引号会说你根本不应该在Category类中使用Products属性