0

OrderLines のコレクションを持つ Order があります。すべての OrderLine には、Product に対する多対 1 があります。すべての注文に対して、デフォルトですべての注文をグリッドに表示する検索ウィンドウがあります。この同じウィンドウを使用して、特定の製品を含むすべての注文をフィルタリングできます。当社の顧客は、1 日あたり約 700 件の注文を生成し、注文には平均約 35 行あります。

検索ウィンドウには、Order オブジェクト自体に格納されている情報のみを表示します。ただし、特定の製品をフィルター処理すると、遅延ロードされた関係が OrderLine のコレクションに初期化され、OrderLine 内の製品に対する多対 1 の関係が初期化されます。各オーダーラインは行ごとにクエリされ、各行には製品テーブルへの個別のクエリがあります。

そのため、注文ごとに平均 35 のクエリを取得してすべての OrderLine を初期化し、さらに 35 のクエリを取得してそのオーダーラインに関連付けられた製品をフェッチします。

すべてのオーダーラインとそれに関連する製品を一度にロードする最良の方法は何ですか? fetch="join" としてオーダーラインの製品に多対 1 をマッピングできることはわかっていますが、それでもオーダーラインと製品を取得するために 35 の単一クエリが必要になります。

参考までに: 現在、すべてを遅延ロードしています。

助言がありますか?ここで Future を使用できますか?

よろしく、テッド

4

3 に答える 3

3

あなたのbatch-sizeセットは何ですか?

遅延読み込みをそのままにして、両方のコレクション マッピングで 35 に設定します。これにより、1 + 35 + 35 クエリが 1 + 1 + 1 に減少します。

<bag ... batch-size='35' ..> 

また、ステファンが指摘したよう batch-size='35'に、クラスにも設定する必要があります。

于 2012-04-27T08:45:44.693 に答える
0

読み込まれたエンティティに対してメモリ内でフィルター操作を行いますか? 通常、問題の製品のオーダーラインを含むオーダーのみに対してクエリを実行します。したがって、クエリ結果に基づいてウィンドウにデータを入力するだけで済みます。データのごく一部だけでウィンドウを埋めるために、すべての注文とすべての注文明細行をトラバースする必要はありません。

通常、データベース サーバーでのフィルタリングは、サーバーからすべてのデータを取得して C# でフィルタリングを行うよりもはるかに高速です。

あなたの説明は私には完全に明確ではありません: 表示する注文を既にフィルタリングしたとすれば、注文明細と製品にアクセスする必要がありますか?
- そうでない場合は、上記の解決策を使用できます。
- はいの場合、フィルタリングされた注文クエリで結合フェッチを実行して、注文明細を注文と一緒に直接ロードできます。Join fetching は <many-to-one> だけでなく <one-to-many> でも可能であるため、いくつかのルート エンティティとその子を同時にロードできます。ルート エンティティに非常に多くの列があり、いくつかの子が存在する場合、クエリがすべての子のルート エンティティのデータを重複して取得するため、いくつかの欠点があります。ただし、多くのシナリオでは (全体的なシステム構成によって異なります)、結合フェッチのメリットがコストを大幅に上回ります。

データをクエリし、次のコードで実際にどのデータが必要になるかが事前に明確でない状況では、バッチ選択 (<batch-size> を使用) を使用すると、データベース ラウンドトリップの数を大幅に減らすことができます。

于 2012-04-29T21:56:13.897 に答える
0

このような場合、注文エンティティ自体は取得しません。「ビュー」クラスを作成し、NHibernate プロジェクトを使用して、関心のある情報のみを含む「ビュー」クラスを返し、それを概要フォームまたはページに配置します。検索時に、関心のある「OrderView」インスタンスを取得する新しいクエリ (1 つだけ) を実行できます。

注文を編集したり、その詳細を表示したりする場合は、エンティティを読み込みます。

于 2012-04-27T08:31:01.327 に答える