我试图了解这可能如何运作。 我所拥有的是从给定的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)
实际上我有点迷茫。也许还有另一种方法来构建它。
欢迎任何帮助,谢谢。
答案 0 :(得分:3)
当返回类型与查询类型
相同时,我不确定为什么要使用resulttransformerreturn NHibernateSession.QueryOver<Tree>()
.Where(t => t.Id.IsIn(ListOfTreeId))
.JoinQueryOver<Apple>(t => t.Apples)
.Where(a => !a.IsRotten)
.List();
更新:编译器在选择ICollection<Apple>
时选择Apple
,因此明确指定JoinQueryOver中的泛型参数
Update2:让它们变得独一无二p>
选择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();