NHibernate QueryOver Where Or on property and nested collect



我有Foo类和Bar

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

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

我知道如何进行单独的查询,但我不确定如何将其合并为 1,中间有OR运算符。基本上,如果一个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))

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

Foo1, Bar1
Foo1, Bar2

为了仅获得干净的父结果集,我们需要将 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)
                )
    )
)

这也期望,那个孩子酒吧有回参考福...这绝对是合法和商业领域模型的支持。

最新更新