Reputation: 1610
I've come unstuck on how to do this:
I have a country entity. A country has zero or more facts. A fact has property called Year.
How can I load a Country entity by its name and eagerly fetch all its facts from a given year, e.g. 2011 (but not load all the other facts)? Is this even possible?
Upvotes: 0
Views: 2159
Reputation: 608
I believe this is possible by using filters in nHibernate. Start out by reading this previous StackOverflow question:
NHibernate - Retrieve parent / children with criteria applied only to children
And also have a look at the nHibernate documentation for more reference:
http://nhibernate.info/doc/nh/en/index.html#filters
Upvotes: 1
Reputation: 1610
UPDATE: I have not solved this. The below HQL only works when facts are present. If there are no facts for a given year then the result is null. I think the correct solution, given my context, is to treat Fact as an aggregate root and issue two queries using Future().
Original post
I have solved this using HQL:
var country = Session.CreateQuery("from Country country left join fetch country.Facts as Facts where Facts.Year in (:years) and country.Name = :name ");
country.SetParameter("name", name);
country.SetParameterList("years", new List<int>() {2012, 2011});
Thanks for the other suggestions. I would be interested in a non-HQL solution to the problem, but this solves it well.
Upvotes: 0
Reputation: 49251
I think this is possible using filtering but it's not a good idea because it violates separation of concerns: your domain model should not be used to present a special view of the data.
Two possibly better options:
IEnumerable<Fact>
. I would pick this option unless I had a measurable performance issue.Future
so that it only requires one trip to the database.Upvotes: 2
Reputation: 3154
EDIT:
var query = session.QueryOver<Country>()
.Fetch(c => c.Facts)
.Eager()
.TransformUsing(NHibernate.Transform.Transformers.DistinctRootEntity)
.Future();
session.QueryOver<Facts>()
.Where(f => f.Year == 2011)
.Future();
var country = query.List().FirstOrDefault();
Upvotes: 0