How to efficiently query with filter on children at different levels?

不问归期 提交于 2019-12-23 03:46:16

问题


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

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