NHibernate: Simplest way to return an object with paged children collection?

坚强是说给别人听的谎言 提交于 2019-12-10 10:12:53

问题


I want to return one Parent object with the children collection eagerly loaded with the requested page (subset) of children objects. What's the best way to achieve this? Filters? Is is possible with an ICriteria query?

I'm using .SetFirstResult() and .SetMaxResults() to do paging for collections of aggregate root results, but is it possible to utilize this withing the aggregate root to select the page of children results?

Something along these lines:

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.
}

UPDATE:

Actually, the eagerly loading requirement is not so important. I just want the paged subset of the child objects loaded when I access them.


回答1:


You can't page and join-fetch child collections in the same query. But you can:

  • Use a query to get the (paged) parents and one to load all the collections for those parents (read http://ayende.com/Blog/archive/2010/01/16/eagerly-loading-entity-associations-efficiently-with-nhibernate.aspx for some concepts)
  • Set batch-size on the collections to your page size. This will accomplish more or less the same, but automatically. There's even a patch that allows changing this dynamically: https://nhibernate.jira.com/browse/NH-2316

Update (for the new requirements):

As you've read, you can use session.CreateFilter to filter/sort/page a child collection. This works and it is supported everywhere.

Additionally, there's a patch (NH-2319; I will convert to an addin, as it's unlikely to be accepted in the trunk) that allows using Linq for that. It's limited to some collection types and requires the relationship to be bidirectional, but allows the following:

var parent = GetParent();
var secondPageOfChildrenByName = parent.Children.AsQueryable()
                                                .OrderBy(c => c.Name)
                                                .Skip(PageSize * 1)
                                                .Take(PageSize)
                                                .ToList();



回答2:


Just read this bit in the NHibernate Documentation 'Querying tips and tricks' section (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();

I'm not entirely sure yet how this will work with a child collection but will try it and update this answer.



来源:https://stackoverflow.com/questions/4284438/nhibernate-simplest-way-to-return-an-object-with-paged-children-collection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!