0

結合を使用せずに、多対多の関係で親の子コレクションの主キーを選択したいと考えています。この例から削除された他の制約により、クエリは親レベル (アイテム) ではなく子レベル (タグ) で発生する必要があります。

Item item = null;
Tag tag = null;

var qoTags = QueryOver.Of<Tag>(() => tag)
             .JoinQueryOver(x => x.Items, () => item)
             .Select(Projections.Group<Item>(() => item.ItemId));

生成する

SELECT Item.ItemId
FROM Tag 
inner join ItemsTags on Tag.TagId  =  ItemsTags.TagId 
inner join Item on ItemsTags.ItemId  =  Item.ItemId 
GROUP BY Item.ItemId 

しかし、理想的には、生成される SQL は次のようになります。

SELECT ItemsTags.ItemId
FROM Tag 
inner join ItemsTags on Tag.TagId  =  ItemsTags.TagId  
GROUP BY ItemsTags.ItemId 

不要な結合が削除され、'group by' 句と 'select' 句がジャンクション テーブルの ID を参照していることに注意してください。

ありがとう!

4

1 に答える 1

0

私の推測では、NHibernate に JoinQueryOver を使用してタグをアイテムに結合するように指示すると、タグからアイテム オブジェクトに到達するためのすべての手順が常に組み込まれると思います。

一歩下がって考えるほどスマートではありません。「ちょっと待ってください。item.ItemId のクエリに射影によるグループがあり、他の項目プロパティは言及されていないので、結合の 1 つをスキップできます」と考えてください。

NHibernate は常に 2 つのマップされたオブジェクト間で必要なすべての結合を作成しようとするため、基準または hql クエリに切り替えてもここで役立つかどうかはわかりません。

あなたは出来る:

  • 直接SQLクエリを実行します(他の基準の束にクエリオーバーのものをすべて使用している場合はあまり良くありません)
  • タグとアイテムの間にマップされたクラスを持つようにモデルを変更します。Tag->one-to-many->TagItem->many-to-one->Item (ユッ! あの匂い嫌いだ!)

以下、どなたか訂正していただきたいです...

于 2012-06-26T06:24:32.243 に答える