1

問題を説明させてください - タイトルでうまく定義できていることを願っていますが、確認したいと思います。

一連のオブジェクト (Foos など) を取得する linq クエリがあります。各 Foo は User への参照を保持します。各 User は Person への参照を保持します。

public class Foo
{
  //properties omitted...
  public User CreatedBy {get;}
}
public class User
{
  //properties omitted...
  public Person Person {get;set;}
}

オブジェクト構造が示唆するように、データベースでは、Foo は多対 1 で User に関連付けられ、User は多対 1 で Person に関連付けられます。

クエリを実行すると、Foos に対して 1 つの SELECT が取得され、次にすべてのユーザーと People に対してそれぞれ SELECT が取得されます。明らかに、いくつかの結合を含む単一の SELECT を好むでしょう。

Foos が常に熱心にユーザーをフェッチすること、またはユーザーが常に熱心に Person をフェッチすることをマッピング構成で指定する必要は必ずしもありませんが、このインスタンスではそれを指定できるようにしたいと考えています。

それを行う方法はありますか?

ありがとう

デビッド

4

3 に答える 3

3

すべてのNHibernateクエリメソッドには、熱心なフェッチを指定する方法があります。

基準については、がありますSetFetchMode

HQLの場合、があります[inner|left] join fetch

Linqの場合、Expand(2.x contrib)/ Fetch(3.x)があります。

SQLの場合はAddJoin

于 2010-08-09T12:45:22.147 に答える
0

Udi DahanRitesh Raoの両方が、NHibernate の動的フェッチ戦略の実装例を提供しています。これは良い出発点になるはずです。

于 2010-08-09T11:42:45.167 に答える
0

ディエゴの良い答えに加えて、バッチ処理を使用することもできます。これにより、あまり苦労せずに N+1 問題が軽減されます。

クラス レベルでバッチ サイズを使用します。

<class name="Person" batch-size="20">
...
</class>

コレクション レベルでバッチ サイズを使用します。

<map
    name="SomeCollection"
    batch-size="20">
  ...
</map>

これらの参照のいずれかがロードされるたびに、NHibernate は次のようなクエリを使用して一度に 20 個をロードします。

select ... from Person where user_fk in (23, 34, 6, 667, 6745, 234 ....)

これはかなり良いですN+1N / 20 + 1

于 2010-08-09T14:18:50.737 に答える