NHibernate QueryOver Where Or on 属性 和嵌套集合

NHibernate QueryOver Where Or on property and nested collection

我有 类 FooBar

class Foo {
    string Name;
    IList<Bar> Bars;
}

class Bar {
    string Name;
}

我有一个输入 q,我想编写一个 NHibernate 查询,如果 Foo.Name 包含 q 或 returns 一个 Foo 对象列表Bars 个对象中的任何一个 Name 包含 q.

我知道如何进行单独的查询,但我不确定如何将其与中间的 OR 运算符合并为 1。基本上,如果 Foo 对象在其名称或其任何 Bars 名称中包含 q,我希望 Foo 对象出现在输出中。

this.sessionFactory.GetCurrentSession()
    .QueryOver<Foo>()
    .Where(x => x.Name.IsInsensitiveLike(q))
    .List();
this.sessionFactory.GetCurrentSession()
    .QueryOver<Foo>()
    .JoinQueryOver<Bar>(x => x.Bars)
    .Where(x => x.Name.IsInsensitiveLike(q))
    .List();

让我们从声明别名开始,以供稍后在查询中使用

Foo foo = null;
Bar bar = null;

现在的第一种方法是加入集合(得到的结果有点难看,每个匹配的子项都有多个父项)

.QueryOver<Foo>(() => foo)
.JoinQueryOver<Bar>(x => x.Occupations, () => bar)
.Where(x => foo.Name.IsInsensitiveLike(q)
         || bar.Name.IsInsensitiveLike(q))

这会起作用,但可能 return 某些行重复父 Foo,以防有更多匹配的子 Bar...

Foo1, Bar1
Foo1, Bar2

为了获得干净的父 result-set,我们需要用子查询替换 JOIN

.QueryOver<Foo>(() => foo)
.Where(Restrictions
    .Or(
        Restrictions.Where(() => foo.Name.IsInsensitiveLike(q)),
        Subqueries
            .WhereProperty(() => foo.ID)
                .In(QueryOver.Of<Bar>(() => bar)
                    .Where(() => bar.Name.IsInsensitiveLike(q))
                    .Select(y => bar.Foo.ID)
                )
    )
)

这也期望,子 Bar 具有对 Foo 的反向引用...这绝对是合法的并且支持业务领域模型。