NHibernate: Easiest way to return an object using a swap collection for children?
I want to return a single parent with a child collection eagerly loaded with the requested page (subset) of child objects. What's the best way to achieve this? Filters? Is it possible with the ICriteria query?
I am using .SetFirstResult () and .SetMaxResults () to create swap for root final result collections, but can I use that using aggregate root to select the child results page?
Something like this:
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 requirement to look forward to loading is not that important. I just want the loadable subsets of the child objects to be loaded when I access them.
source to share
You cannot create child collections and join a selection in the same query. But you can:
- Use a query to get the (unloaded) parents and one to load all 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
in collections to the size of your page. It will be more or less the same, but automatically. There's even a patch that allows for dynamic change: https://nhibernate.jira.com/browse/NH-2316
Update (for new requirements):
As you read, you can use session.CreateFilter
to filter / sort / page a child collection. It works and is supported everywhere.
Also, there is a patch ( NH-2319 ; I will convert to addin as it is unlikely to be accepted in the trunk) that allows Linq to be used for this. It is 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();
source to share
Just read this bit in the NHibernate Documentation. Section "Tips and tricks" (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 quite sure yet how this would work with the child collection, but will try and update this answer.
source to share