问题
I have 3 classes with one to many relationships
A has many B has many C
I want to load all of my data where either of two conditions are true:
B.someField is in a list of strings
C.someOtherField is in that same list of strings
Sometimes B will be the match, sometimes C will be the match. I need to load all matches, and load them for the full levels.
In other words, if B.someField matches, I want to load that B, and its parent A, and all children C.
Likewise, if C.someOtherField matches, I want to load its parent B and B's parent A.
Is there an efficient way make this query? How would you do it in nHibernate?
回答1:
When quering over multiple child collections using NHibernate, I tend to prefer to use the LINQ query syntax over lambdas because not only is it much easier to write but the code looks cleaner.
Take this example which should point you in the right direction:
var listOfString = new List<string>() { "String1", "String2" };
var customers =
(
from a in session.Query<A>()
from b in a.B
from c in b.C
where a.Status == "Active"
&& listOfStrings.Contains( b.SomeField )
&& listOfStrings.Contains( c.someOtherField )
select a )
.ToList();
By using the LINQ query syntax, we can easily add multiple FROMs to gain access to the child collections. Then it's just a matter of apply your WHERE conditions. For your particular case, you would simply use LINQ's Contains() method which equates to SQL's IN operator.
It also sounds like you are wanting to load all the child collections into memory as well so be sure to use NHibernate's .Fetch() method to eagerly load that data like so:
var customers =
(
from a in session.Query<A>()
from b in a.B
from c in b.C
where a.Status == "Active"
&& listOfStrings.Contains( b.SomeField )
&& listOfStrings.Contains( c.someOtherField )
select a )
.Fetch( x => x.B )
.ThenFetchMany( x => x.First().C )
.ToList();
FYI, using the .First() inside the .ThenFetchMany() method above is a trick I learned from the NHibernate's Jira issue tracker website: https://nhibernate.jira.com/browse/NH-2972?focusedCommentId=22150&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-22150
来源:https://stackoverflow.com/questions/12313172/how-to-efficiently-query-with-filter-on-children-at-different-levels