NHibernate:返回具有分页子集合的对象的最简单方法?

NHibernate:返回具有分页子集合的对象的最简单方法?,nhibernate,paging,Nhibernate,Paging,我想返回一个父对象,其中的子对象集合急切地加载了请求的子对象页面(子集)。实现这一目标的最佳方式是什么?过滤器?ICriteria查询是否可行 我正在使用.SetFirstResult()和.SetMaxResults()对聚合根结果的集合进行分页,但是是否可以将其与聚合根一起使用来选择子结果的页面 大致如下: public class Parent{ int Id; IList<Child> Children; } public Parent GetWithPagedChild

我想返回一个父对象,其中的子对象集合急切地加载了请求的子对象页面(子集)。实现这一目标的最佳方式是什么?过滤器?ICriteria查询是否可行

我正在使用.SetFirstResult()和.SetMaxResults()对聚合根结果的集合进行分页,但是是否可以将其与聚合根一起使用来选择子结果的页面

大致如下:

public class Parent{
int Id;
IList<Child> Children;
}


public Parent GetWithPagedChildren(int id, int page, int pageSize, out int count)
{
    //Query

    return Parentresult; //With one page of children populated.
}
公共类父类{
int-Id;
孤独症儿童;
}
公共父级GetWithPagedChildren(int-id、int-page、int-pageSize、out-int-count)
{
//质疑
return Parentresult;//填充一页子项。
}

更新:


事实上,急切的加载要求并不那么重要。我只希望在访问子对象时加载子对象的分页子集。

您不能在同一查询中分页并加入fetch子集合。但你可以:

  • 使用一个查询获取(分页的)父对象,使用一个查询加载这些父对象的所有集合(阅读了解一些概念)
  • 将集合上的批大小设置为页面大小。这将或多或少实现相同的功能,但会自动完成。甚至有一个补丁允许动态更改此选项:
更新(针对新要求):

如前所述,您可以使用
session.CreateFilter
对子集合进行筛选/排序/分页。这是可行的,并且得到了各地的支持

此外,还有一个补丁(;我将转换为一个addin,因为它不太可能在主干中被接受)允许使用Linq实现这一点。它仅限于某些集合类型,并且要求关系是双向的,但允许以下情况:

var parent = GetParent();
var secondPageOfChildrenByName = parent.Children.AsQueryable()
                                                .OrderBy(c => c.Name)
                                                .Skip(PageSize * 1)
                                                .Take(PageSize)
                                                .ToList();
只需阅读以下内容:


我还不完全确定这将如何与儿童收藏一起使用,但将尝试并更新此答案。

很遗憾,这一定是一种非常常见的情况。特别是当坚持DDD规则并且仅通过聚合根遍历访问对象时(我可以构建一个子存储库,但这意味着每个实体都有一个存储库,而不仅仅是聚合根)。我认为第一个示例不会有任何帮助。第二个选项是否仅在v3中可用?我使用的是v2.2。不幸的是,第二个选项在2.x中可用,这就是我现在使用的,并且与DDD一致。好的,谢谢。我读了ayende关于这个()的这篇(有点旧)帖子——他说这只支持MSSQL。你知道这是否已经改变了吗?这是关于批量更新,而不是抓取,它与MSSQL和Oracle一起工作。批量抓取工作将在所有数据库中完成。这些更新看起来很棒-谢谢迭戈。我似乎错过了我补充的赏金的结尾——为此道歉。你为什么要传呼孩子们?它们是否太多而无法放入内存?@Stefan:当我知道只需要一小部分时,从数据库获取整个子集合似乎是错误和浪费的。
//Collections are pageable by using the IQuery interface with a filter:

IQuery q = s.CreateFilter( collection, "" ); // the trivial filter
q.setMaxResults(PageSize);
q.setFirstResult(PageSize * pageNumber);
IList page = q.List();