3

複数のネストされたアソシエイトを持つデータベースがあります。基本的に、構造は次のとおりです。

Order -> OrderItem -> OrderItemPlaylist -> OrderPlaylistItem -> Track -> Artist

特定の日付に販売されたすべての注文に基づいてレポートを生成する必要があります。必要な情報を生成するには、言及されたすべての関連付けをトラバースする必要があります。

すべてのテーブルを一緒に結合しようとすると、6 つのテーブルを結合することになることを考えると、多くの冗長データを含む非常に大きなデカルト結合になるため、やり過ぎです。以下のコード:

q.Left.JoinQueryOver<OrderItem>(order => order.OrderItems)
     .Left.JoinQueryOver<OrderItemPlaylist>(orderItem => orderItem.Playlist)
     .Left.JoinQueryOver<OrderItemPlaylistItem>(orderItemPlaylist => orderItemPlaylist.PlaylistItems)
     .Left.JoinQueryOver<Track>(orderItemPlaylistItem => orderItemPlaylistItem.Track)
     .Left.JoinQueryOver<Artist>(track => track.Artist)

上記は機能しますが、それぞれにいくつかの注文アイテムがあり、それぞれが複数のトラックで構成されるプレイリストを含む少数の注文でも、結果は数千のレコードに爆発し、追加の注文ごとに指数関数的に増加します。

最善かつ最も効率的なアプローチは何でしょうか? 私は現在、データベースクエリの数を大幅に削減するバッチロードを有効にしようとしましたが、それでも私には良いアプローチとは思えませんが、「簡単な回避策」のようです。

膨大な量のデータがあるため、すべてのデータを 1 回の SQL クエリでロードする必要はありません。アソシエーションごとに 1 つの SQL クエリがあれば完璧だと思います。理想的には、最初にすべての注文を取得し、次にその注文のすべての注文アイテムを取得して関連するコレクションにロードし、次に各注文アイテムのプレイリストをロードする、というようになります。

.RootCriteriaまた、 Criteria API にアクセスして使用できるため、特に QueryOver である必要はありません。

どんな助けでも大歓迎です!

4

3 に答える 3

0

これがあなたが探しているものだと思います

http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

于 2011-08-19T20:29:05.567 に答える
0

1つのSQLクエリが必要な場合、これによってどのSQL構文が生成されると思いますか?JOIN1つのSQLクエリを実行する場合、sの長いシーケンスを回避することはできないと思います。

私がすることは、いくつかのクエリを使用して、レベルごとにエンティティを取得することだと思います。

于 2011-05-26T13:19:23.280 に答える
0

SQL でできる限りクエリを定義し、実行計画を調べて最適な方法 (およびインデックスが十分かどうか) を見つけることから始める必要があります。

その時点で、自分が何を目指しているかがわかります。その後、HQL、QueryOver、さらには LINQ でクエリを試してコーディングし、NHibernate の SQL ライター、または優れた NHProfiler http://wwwを使用して結果を確認するのはかなり簡単です。 .nhprof.com .

いくつかのクエリで終わることについては、おそらく正しいでしょう。Criteria または QueryOver で「Future」コマンドを使用して、(互いに依存しない) できるだけ多くの旅行を 1 回の旅行にまとめることで、それらを高速化します。詳細については、こちらをご覧ください: http://ayende.com/blog/3979/nhibernate-futures

于 2011-06-27T17:13:11.647 に答える