2012-06-26 69 views
0

我想在不使用連接的情況下以多對多關係選擇父級子集合的主鍵。由於此示例中已刪除的其他約束條件,查詢必須發生在子級別(Tag)而不是父級別(Item)上。在nHibernate中未加入的情況下選擇子集合ID

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 

通知不必要加入被去除,並且 '組由' 和 '選擇' 的條款在引用聯結表的ID。

謝謝!

+0

您是否比較了兩個查詢的實際查詢計劃?這兩個查詢可能以相同的方式執行。 – biziclop

+0

是的,執行計劃顯示加入項目表的一小筆費用。通常情況下,我會接受這個成本,但Item表有兩個子類(表)。因此,與Item結合會導致3次無關聯,約佔查詢成本的60%。 – Sardonic

回答

0

我的猜測是,當你告訴NHibernate你想用JoinQueryOver加入標籤到物品時,它總是會把所有的步驟從標籤獲取到物品對象。

它不是足夠聰明,退一步,認爲「等等,在查詢item.ItemId有一組通過投影並沒有其他項目屬性被提及,所以我可以跳過加入的一個」

我不確定即使切換到條件或hql查詢也會對此有所幫助,因爲NHibernate會一直嘗試在您的兩個映射對象之間創建所有必需的連接。

,你可以:

  • 做一個直接的SQL查詢(不是很大,如果你使用的所有queryover工具和一堆其他標準)
  • 更改模型有標籤之間的映射類和項目。標籤 - >一對多 - >標籤項目 - >多對一 - >項目(YUK!我不喜歡那個的氣味!)

我想要一個人來糾正我以下...