2

NHibernate Criteria が返すエンティティの数を制限しようとしています。標準では SetMaxResults を使用するようですが、基準が多対多の関係で LEFT OUTER JOIN を含む場合、これは適切に機能しません。

例:

犬には飼い主がいて (多対多の関係)、ある一連の飼い主に属する最大 10 匹の犬を取得する必要があります。やっている

session.CreateCriteria<Dog>()
  .CreateAlias("Owners", "Owners")
  .Add(Restrictions.In("Owners.Id", idCollection)
  .SetMaxResults(10)
  .List<Dog>();

次のようなSQLクエリに変換されます

SELECT TOP(10) * FROM DOGS d
  LEFT OUTER JOIN OWNERS_DOGS od ON d.id = od.id
  WHERE od.OWNER_ID IN (:valueone, :valuetwo)

TOP の制限が早すぎるため、条件に一致する複数の所有者を持つ犬が、制限の 10 に対して複数回カウントされます。NHibernate に、最初の X の犬オブジェクトのみを水和させたいことを明確に伝える方法はありますか? おそらく、データベースに対して完全な SELECT を実行することから抜け出すことはできませんが、表示するのは 10 匹だけなので、システム内のすべての犬をロードすることを避けることができればよいでしょう。

4

1 に答える 1

2

この場合の解決策はサブクエリです。必要なのは、犬の所有者によってフィルタリングされ、 Dog IDを返す内部 SELECTを作成することです。次に、Dogs にクエリを実行し、そのサブクエリでフィルター処理します。最後に、フラット構造で実行されている間、ページングは​​正しくなります。

詳細については、この回答を参照してください: https://stackoverflow.com/a/14080092/1679310

サブクエリ15.8. 切り離されたクエリとサブクエリ:

DetachedCriteria subQuery = DetachedCriteria.For(typeof(Dog))
    // WHERE conditions go here
    .SetProjection( Projections.Property("ID") )
;

ページングが正しいクエリ

session.CreateCriteria(typeof(Dog))
    .Add(Subqueries.PropertyEq("ID", subQuery));
    // PAGING goes here
    .SetMaxResults(10)
    .List();
于 2013-02-06T05:13:56.143 に答える