I have a recursive one-to-many relationship that has the default lazy value of true. What code can I write against the NH API that will efficiently retrieve the ENTIRE tree
See Ayende's site: Efficiently Selecting a Tree. I have successfully used this technique in my own applications. With ICriteria, it looks like this:
session.CreateCriteria<Category>()
.SetFetchMode("SubCategories", FetchMode.Join)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Category>()
.Where(x => x.ParentCategory == null);
The main difference between this version and what you tried is how the "ParentCategory == null" filter is applied. It has to be left out of the query that is sent to the database in order to retrieve the whole tree - but we still need the query to only return the root nodes of the tree, so we'll use linq to find those after the database query has completed.
Not sure if it helps but take a look at : map a tree in NHibernate
I used Daniel's code as a bases for solving the problem. I also experimented with the equivalent HQL that I shared below. The HQL executed slightly faster, but I went with ICriteria since I could then choose between FetchModel.Join and FetchModel.Lazy.
session.CreateQuery( "from Category as c left join fetch c.SubCategories" )
.SetResultTransformer( new DistinctRootEntityResultTransformer() )
.List<Category>()
.Where( c => c.ParentCategory == null );