NHibernate:返回带有分页子集合的对象的最简单方法是什么?

3
我希望能够返回一个包含子集合的父对象,子集合需要被提前加载。请问如何实现呢?可以使用过滤器吗?或者可以通过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.
}

更新:

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


你为什么想对孩子进行分页?是因为他们太多而无法放入内存吗? - Stefan Steinegger
@Stefan:当我知道只需要一个小子集时,从数据库中获取整个子集合似乎是错误和浪费的。 - UpTheCreek
2个回答

4
您不能在同一查询中分页和联接获取子集合。但是您可以:

更新(针对新要求):

如您所读,您可以使用session.CreateFilter来过滤/排序/分页子集合。这有效并且在任何地方都支持。

此外,还有一个补丁(NH-2319),可以将其转换为插件,因为它不太可能被接受到主干中。该补丁允许使用Linq进行操作,但仅限于某些集合类型,并要求关系是双向的,但允许执行以下操作:
var parent = GetParent();
var secondPageOfChildrenByName = parent.Children.AsQueryable()
                                                .OrderBy(c => c.Name)
                                                .Skip(PageSize * 1)
                                                .Take(PageSize)
                                                .ToList();

很遗憾,这一定是一个非常普遍的情况。特别是在坚持DDD规则并且只通过聚合根遍历访问对象时(我可以构建子存储库,但这意味着为每个实体而不仅仅是聚合根创建存储库),第一个示例不会有所帮助。第二个选项只在v3中可用吗?我正在使用v2.2,不幸的是。 - UpTheCreek
第二个选项在2.x中可用,这是我现在正在使用的版本,并且与DDD一致。 - Diego Mijelshon
好的,谢谢。我读了ayende在这篇(http://ayende.com/Blog/2006/09/16/BatchingSupportInNHibernate.aspx)略旧的文章 - 他说这只支持MSSQL。你知道这是否已经改变了吗? - UpTheCreek
这是关于批量“更新”,而不是获取,并且它适用于MSSQL和Oracle。批量获取适用于所有数据库。 - Diego Mijelshon
那些更新看起来很不错 - 谢谢迭戈。不过我好像错过了我添加的悬赏的截止日期 - 对此我很抱歉。 - UpTheCreek

1

刚刚在NHibernate文档“查询技巧和窍门”章节(13.13)中读到了这一部分:

//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();

我还不确定如何在子集合中使用它,但我会尝试并更新这个答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接