3

以下のようなクラスグラフがあります。

この例を使用しているのは、作業しているドメインを説明するよりも簡単だからです。

public class Cheque {

   public FinanceAccount Account {get;set;}

   public Customer customer {get;set;}

   public Branch Branch {get;set;}
}

ChequeエンティティはManyToOne、残りの3つのエンティティと関係があります。

今のところ、関係は双方向ではありません

、、ChequesをロードするためにN + 1を取得しないように、リストをフェッチする効果的な先物クエリを作成するにはどうすればよいですか?AccountCustomerBranch

左結合を使用してみましたが、簡略化されたSQLを使用してこれを実行できるかどうかを知りたいと思いました

4

1 に答える 1

3

必要な結果を得ることができます(N + 1なし)-しかし、Futuresはそのための正しいNHibernate機能ではありません。それらを使用することはできますが、many-to-oneエンティティをフェッチするための秘訣は他の場所にあります(以下を参照)。ここに記載されている先物:http://ayende.com/blog/3979/nhibernate-futuresの意味:

... Future()とFutureValue()は基本的に、クエリの実行を後日延期する方法として機能します。その時点で、NHibernateはアプリケーションの実行内容に関する詳細情報を取得し、それに応じて最適化します。

したがって、より多くのクエリを1つのバッチに入れることができます。クエリは、たとえば、次のような一連のクエリである可能性があります。

  • トータルチェック
  • 最初の20の予測を確認します
  • 先週の最大引き出し額

したがって、この場合、「異なる」タイプのクエリをに入れることができFutureます。

ただし、many-to-oneN + 1なしでエンティティをフェッチするには、標準のCriteriaAPIを使用できます。したがって、これらのプロパティが、selectをフェッチとしてレイジーとしてマップされている場合でも、次のようになります。

<many-to-one name="Account" class="FinanceAccount" column="AccountId" 
       lazy="proxy" fetch="select"/>

この基準は、左結合で1つの選択のみを作成します。

var list = session.CreateCriteria<Cheque>()
  .SetFetchMode("Account", NHibernate.FetchMode.Join)
  .SetFetchMode("customer", NHibernate.FetchMode.Join)
  .SetFetchMode("Branch", NHibernate.FetchMode.Join)
  .Future<Cheque>()
  // or
  // .List<Cheque>() ... will be the same right now
  ;

これにより、Checkとその参照プロパティを結合するSQLselectステートメントが1つだけになります。

于 2012-12-01T17:32:34.967 に答える