這裏是我的建議:
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