NHibernate QueryOver中的子查询父ID

时间:2011-12-15 20:56:02

标签: c# nhibernate subquery queryover

我试图了解这可能如何运作。 我所拥有的是从给定的ID列表中获取所有没有腐烂苹果的树。 看起来很简单,但我对NHibernate很新,在SQL中不太好,你可以看到我被卡住了。

我在这里写下了这段代码:

Tree treeitem = null;

QueryOver<Apple> qapple = QueryOver.Of<Apple>()
    .Where(x => (!x.IsRotten))
    .And(Restrictions.IdEq(Projections.Property<Tree>(y => y.Id)))
    // Or this one...
    //.And(Restrictions.EqProperty(
    //     Projections.Property<Apple>(y => y.Tree.Id),
    //     Projections.Property<Tree>(y => y.Id)))
    .Select(x => x.Id);

return this.NHibernateSession.QueryOver<Tree>()
    .Where(x => x.Id.IsIn(ListOfTreeId))
    .WithSubquery.WhereExists<Apple>(qapple)
    .SelectList(list => list
        .Select(z => z.Id).WithAlias(() => treeitem.Id)
        .Select(z => z.Name).WithAlias(() => treeitem.Name)
        .Select(z => z.Type).WithAlias(() => critem.Type)
    .TransformUsing(Transformers.AliasToBean<Tree>())
    .List<T>();

我得到的伪SQL是这样的:

SELECT id, name, type FROM trees WHERE id IN (1, 2, 3)
AND EXIST(SELECT id FROM apples WHERE NOT rotten AND apples.idtree = apples.id)

正如您所看到的那样,使用相同的表ID的子查询存在问题,而不是类似的情况:

EXIST(SELECT id FROM apples WHERE NOT rotten AND apples.idtree = tree.id)
实际上我有点迷茫。也许还有另一种方法来构建它。 欢迎任何帮助,谢谢。

1 个答案:

答案 0 :(得分:3)

当返回类型与查询类型

相同时,我不确定为什么要使用resulttransformer
return NHibernateSession.QueryOver<Tree>()
    .Where(t => t.Id.IsIn(ListOfTreeId))
    .JoinQueryOver<Apple>(t => t.Apples)
        .Where(a => !a.IsRotten)
    .List();

更新:编译器在选择ICollection<Apple>时选择Apple,因此明确指定JoinQueryOver中的泛型参数

Update2:让它们变得独一无二

选择1)

...
    .SetResultTransformer(Transformers.DistinctRootEntity());
    .List();

选择2)

Tree treeAlias = null;

var nonRottenApples = QueryOver.Of<Apple>()
    .Where(a => !a.IsRotten)
    .Where(a => a.Tree.Id == treeAlias.Id)
    .Select(x => x.Id);   <- optional

return NHibernateSession.QueryOver(() => treeAlias)
    .Where(t => t.Id.IsIn(ListOfTreeId))
    .WithSubquery.WhereExists(nonRottenApples)
    .List();