NHibernate中的分页

NHibernate中的分页,nhibernate,domain-driven-design,paging,Nhibernate,Domain Driven Design,Paging,假设我有一个域模型,它有一个名为Blog的类,该类有一个名为blogoEntries的属性(包含blogoEntry类型的对象)。如果我有一个包含两个表“Blog”和“BlogEntry”的数据库模型,那么我不可能为一个Blog创建1000个Blog条目。如果我要在一个网站上显示博客,我一次只想显示20个博客条目,所以我必须使用某种分页。我显然不想一直从数据库中提取1000条记录 我该怎么做呢?BlogEntries属性甚至应该在Blog域对象中,或者可能在respository中?我仍然希望有

假设我有一个域模型,它有一个名为Blog的类,该类有一个名为blogoEntries的属性(包含blogoEntry类型的对象)。如果我有一个包含两个表“Blog”和“BlogEntry”的数据库模型,那么我不可能为一个Blog创建1000个Blog条目。如果我要在一个网站上显示博客,我一次只想显示20个博客条目,所以我必须使用某种分页。我显然不想一直从数据库中提取1000条记录

我该怎么做呢?BlogEntries属性甚至应该在Blog域对象中,或者可能在respository中?我仍然希望有可能添加博客条目,以及获得现有的页面结果。NHibernate映射是什么样子的

Blog/BlogEntry只是一个例子,它也可以是一个客户/订单示例或任何其他主/细节场景


请开导我

对于博客条目的集合,可以使用属性。它将允许您不选择数据库中的所有集合,只选择必需的值。

您必须访问它自己存储库中的博客条目才能获得分页列表


编辑:为什么要投否决票?这是错误的吗?

我会让BlogEntry成为自己的聚合根目录,拥有自己的存储库。通过查询BlogEntry存储库中具有给定BlogID的所有BlogEntry,可以获得特定博客的BlogEntry实例。除此之外,我无法提供关于存储库的详细信息,因为实现存储库有几种不同的策略(一个通用存储库与多个存储库,单独的查找器方法与一个接受复杂规范对象的方法,等等)。存储库的finder方法应该支持分页

public class Blog
{
    public int ID {get;set;}
    // other stuff
}

public class BlogEntry
{
    public int ID {get;set;}
    public int BlogID {get;set;}
}

public class BlogEntryRepository
{
    public IEnumerable<BlogEntry> FindByBlogID(
        int blogID, int pageIndex, int pageSize) 
    {
        // implementation
    }
}
在数据库中,您将返回多行,每个博客条目一行。(我还喜欢返回多个结果集,以便在一次数据库往返中从所有相关表中获取所有行。我还使用SQL 2005的ROW_VERSION函数来启用数据库分页。)


我通常更喜欢第二种方法,除非典型的用法显示与博客相关联的博客条目实例数量过高(例如,超过几千个)。太多的int数组会让我对性能和内存产生警惕。

当导航到第2页时,这仍然会加载第一页的所有值。我喜欢你的答案,这很有意义。“除非”部分呢?如果数组很大,您会怎么做。从性能内存的角度来看(如您所写),20岁以后从另一台机器上的数据库读取1000条记录似乎是个坏主意。在“除非”的情况下,我会选择第一种方法。我添加了示例代码以使这两种方法更清晰。在第二种方法中,对于blogentryId集合,即使您可能要求数百或数千行,您也只要求每行有一个整数列。确定这是否可接受的唯一方法是在某种程度上确定性能要求,并进行一些初步测试。或者只使用第一种方法。
public class Blog
{
    public int ID {get;set;}
    public IEnumerable<int> BlogEntryIDs {get;set;}
    // other stuff
}

public class BlogEntry
{
    public int ID {get;set;}
    public int BlogID {get;set;}
}

public class BlogEntryRepository
{
    public IEnumerable<BlogEntry> Get(IEnumerable<int> blogEntryIDs) 
    {
        // implementation
    }
}
// get the second page
var entries = 
  blogEntryRepo.Get(blog.BlogEntryIDs).Skip(1 * PAGE_SIZE).Take(PAGE_SIZE);