如何有效地使用过滤器查询不同级别的儿童?

时间:2012-09-07 06:52:09

标签: nhibernate

我有3个一对多关系的课程

A has many B has many C

我想在两个条件都满的情况下加载我的所有数据:

B.someField is in a list of strings

C.someOtherField is in that same list of strings

有时候B会匹配,有时候C会匹配。我需要加载所有匹配项,并将它们加载到完整级别。

换句话说,如果B.someField匹配,我想加载那个B及其父A和所有子C.

同样,如果C.someOtherField匹配,我想加载其父B和B的父A。

是否有一种有效的方法来进行此查询?你会如何在nHibernate中做到这一点?

1 个答案:

答案 0 :(得分:0)

当使用NHibernate查询多个子集合时,我倾向于使用LINQ查询语法而不是lambdas,因为它不仅更容易编写,而且代码看起来更清晰。

以此示例指出正确的方向:

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();

通过使用LINQ查询语法,我们可以轻松添加多个FROM来访问子集合。那么这只是应用你的WHERE条件的问题。对于您的特定情况,您只需使用LINQ的Contains()方法,该方法等同于SQL的IN运算符。

听起来你也想要将所有子集合加载到内存中,所以一定要使用NHibernate的.Fetch()方法来急切地加载这些数据,如下所示:

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();

仅供参考,在上面的.ThenFetchMany()方法中使用.First()是我从NHibernate的Jira问题跟踪器网站上学到的一个技巧:https://nhibernate.jira.com/browse/NH-2972?focusedCommentId=22150&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-22150