1

我有 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 中做到这一点?

4

1 回答 1

0

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

举个例子,它应该为你指明正确的方向:

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

于 2012-09-07T19:17:48.683 回答