ここに私の提案です:
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>();
次のようにアイデアがあります:すべての子供を見つけるそれらはnames
のエントリの1つのようなName
を持っています。それらの子供をグループ化する。Parent
。 Child
には、それぞれの親にマップされたParent
プロパティが必要ですが、とにかくそれは良い考えです。同じサイズ(またはそれ以上)のグループすべてについて、Ge
をEq
に置き換えることができるように、names.Length
を返す。グループのサイズがnames.Length
に等しい場合、すべての名前はであり、親の2人の子供が同じ名前のを持たないと仮定されているためです。
生成されたクエリ:
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
行は必須ではありません。クエリ):Fetch
なし
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():
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
名前が正確にあるすべての親が必要ですか?長さの子、名前の各エントリに1つの子があります(その名前を名前として持つ)か? –
これ以上は持っていないので、親は10人の子供を持つことができますが、名前リストの3つだけ一致する必要があります。良いことだ – shenku