这里是我的建议:
var parents = session.QueryOver<Child>()
.WhereRestrictionOn(x => x.Name).IsIn(names)
.Select(Projections.Group<Child>(x => x.Parent))
.Where(Restrictions.Ge(Projections.Count<Child>(x => x.Parent), names.Length))
.List<Parent>();
的想法是如下:找到所有的孩子有Name
像names
条目之一。通过Parent
将这些孩子分组。你的Child
将需要一个Parent
属性映射到各自的父母为此,但这是一个好主意无论如何。对于大小等于(或大于,但不应该发生,所以你可以用Eq
代替Ge
)names.Length
的所有组,返回它们的父代;因为如果该组的大小等于names.Length
,则所有名称都被发现假设父母的两个孩子没有相同的名字。
生成的查询:
SELECT
this_.Parent as y0_
FROM
Child this_
WHERE
this_.Name in (
/* */
)
GROUP BY
this_.Parent
HAVING
count(this_.Parent) >= /* names.Length */;
我创建了返回希望的结果一个测试应用程序。
如果你需要对父母做更多的事情,比如分页或者抓取孩子,你可以将这个问题分解为一个子查询(请注意,.Fetch(x=>x.Children).Eager
行不是必需的,这只是一个例子,你可以继续使用查询):
var parentSubQuery =
QueryOver.Of<Child>()
.WhereRestrictionOn(x => x.Name).IsIn(names)
.Select(Projections.Group<Child>(x => x.Parent))
.Where(Restrictions.Ge(Projections.Count<Child>(x => x.Parent), names.Length));
var parents = session.QueryOver<Parent>()
.Fetch(x=>x.Children).Eager // not necessary, just an example
.WithSubquery.WhereProperty(x => x.Id).In(parentSubQuery)
.List();
SQL(不Fetch
):
SELECT
this_.Id as Id1_0_
FROM
Parent this_
WHERE
this_.Id in (
SELECT
this_0_.Parent as y0_
FROM
Child this_0_
WHERE
this_0_.Name in (
/* names */
)
GROUP BY
this_0_.Parent
HAVING
count(this_0_.Parent) >= /* names.length */
);
更新:
如果家长< - >孩子多到多,事情变得有些棘手:
Parent parent = null;
var parentSubQuery = QueryOver.Of<Child>()
.WhereRestrictionOn(x => x.Name).IsIn(names)
.JoinQueryOver(x => x.Parents,() => parent)
.Where(Restrictions.Ge(Projections.Count(() => parent.Id), names.Length))
.Select(Projections.Group(() => parent.Id));
var parents = session.QueryOver<Parent>()
.WithSubquery.WhereProperty(x => x.Id).In(parentSubQuery)
.List();
的主要区别在于不是通过Child
直接Parent
属性分组我首先需要参加家长集合。为了引用每个父母,我引入了别名parent
。
生成的SQL是非常接近原来的做法:
SELECT
this_.Id as Id2_0_
FROM
Parent this_
WHERE
this_.Id in (
SELECT
parent1_.Id as y0_
FROM
Child this_0_
inner join
ChildToParent parents3_
on this_0_.Id=parents3_.ChildId
inner join
Parent parent1_
on parents3_.ParentId=parent1_.Id
WHERE
this_0_.Name in (
/* names */
)
GROUP BY
parent1_.Id
HAVING
count(parent1_.Id) >= /* names.Length */
);
对于我的测试场景中它的作品,所以希望它会为你。
要清楚,孩子们应该匹配列表中的每个项目。 – shenku 2012-03-06 22:38:23
你是否想要所有父母都有姓名的正确名称?长儿童,哪里有一个名字的儿童(名称中包含该条目)? – 2012-03-06 23:02:05
不,他们可以有更多的,所以父母可以有10个孩子,但只需要匹配名单中的3。 (例如) – shenku 2012-03-06 23:03:58