C# 一对多映射。亚硝酸铵

C# 一对多映射。亚硝酸铵,c#,nhibernate,one-to-many,C#,Nhibernate,One To Many,我正在看《NHibernate 3初学者指南》一书,发现了有趣的提示: 在实际的库存应用程序中,您可能希望避免 将产品集合按原样放置在类别实体上 一个类别可能有数百个,甚至数千个 相关产品。装载整个庞大的产品集合 对于给定的类别,这将是不明智的,并将导致申请 响应时间不令人满意的 Tip就在一对多关系建立的例子之后。实体为产品和类别。这个例子非常简单: public class Category : Entity // Entity probably contains an `Id` prope

我正在看《NHibernate 3初学者指南》一书,发现了有趣的提示:

在实际的库存应用程序中,您可能希望避免 将产品集合按原样放置在类别实体上 一个类别可能有数百个,甚至数千个 相关产品。装载整个庞大的产品集合 对于给定的类别,这将是不明智的,并将导致申请 响应时间不令人满意的

Tip就在一对多关系建立的例子之后。实体为
产品
类别
。这个例子非常简单:

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; }
}
公共类类别:实体//实体可能包含'Id'属性
{
私人上市产品;
公共字符串CategoryName{get;set;}
公共字符串说明{get;set;}
公共IEnumerable产品{get{return Products;}}
}  
公共类产品:实体
{
公共十进制单价{get;set;}
公共字符串ProductName{get;set;}
公共类别{get;set;}
}
那么,一对多关系的真实例子是什么


对于这个例子来说,仅仅将
Category
作为
String
属性放在产品实体中就足够了吗?

我想引用会说,您根本不应该在Category类中使用Products属性。

您可能想看看Nhibernate的lazy属性。它允许您不加载该属性除非我们明确要求


让我们问不同的问题:如果应用程序应该在树状视图中显示类别,那么在展开类别节点时将列出所有产品的控件会怎么样?当你想展示所有产品时,除了。。。实际查询数据库并加载所有产品

这实际上是非常常见的现实场景,最简单的方法之一就是简单地拥有
Category.Products
属性。当然,拥有这样的属性没有什么错,但真正的问题是应该如何管理这些对象

幸运的是,您不必使用单一类别拉动来拉动所有产品<代码>类别。产品可以标记为延迟加载(与急切加载相反,可以找到更多信息)。这意味着,加载类别不会查询其产品的数据库。相反,NHibernate将为
产品
创建对象,稍后可以在实际需要时初始化(想想用户扩展类别节点)


为了回答你的问题


如果单个产品只绑定到一个类别,那么它就是一个很好的现实生活中的一对多关系示例。但是,如果产品可以由多个类别来描述,那么它是多对多关系。

如果您同时避免IList属性,您仍然可以获得某个类别的产品,例如如下所示:

var products = session.QueryOver<Product>().Where(p => p.Category == someCategory).List();
var products=session.QueryOver().Where(p=>p.Category==someCategory.List();
但您现在可以进行分页、过滤、获取顶级产品等操作:

var product = session.QueryOver<Product>().Where(p => p.Category == someCategory).OrderBy(p => p.Relevance).Take(1).SingleOrDefault();
var product=session.QueryOver().Where(p=>p.Category==someCategory).OrderBy(p=>p.Relevance).Take(1.SingleOrDefault();

如果它是一个简单的IList属性,则没有。一般来说(根据我的经验),双向关联越少,查询粒度就越好。此外,它还降低了储蓄的复杂性。

维护一对多属性有很多原因。例如:如果我有一个订单,我可以选择在该订单实体上有一个Items集合。由于订单项目在订单上下文之外毫无意义,我甚至可以选择不使用OrderItemRepository。