0

我想在不使用连接的情况下以多对多关系选择父子集合的主键。由于已从此示例中删除了其他约束,因此查询必须发生在子级别(Tag)而不是父级别(Item)上。

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 的查询中有一个按投影分组,并且没有提到其他项目属性,所以我可以跳过其中一个连接”

我不确定切换到标准或 hql 查询是否会有所帮助,因为 NHibernate 将始终尝试在您的 2 个映射对象之间创建所有必要的连接。

你可以:

  • 做一个直接的 sql 查询(如果你将所有这些查询的东西用于一堆其他条件,那就不好了)
  • 更改您的模型以在 Tag 和 Item 之间具有映射类。Tag->one-to-many->TagItem->many-to-one->Item(哎呀!我不喜欢那个味道!)

我希望有人在下面纠正我...

于 2012-06-26T06:24:32.243 回答