在我的查询中我使用多个表,其中一些表不能设置为正常的nhibernate关系,所以我不得不返回由单个列而不是实体实例组成的行。我想要返回的一个属性是包/列表,我的查询是这样的:
select p.ID, p.SomeOtherField, elements(p.MappedBagField), o.AnotherField ... from Parent p, OtherClass o, ...
查询有效,但我遇到的问题是,当包包含多个链接记录时,我将返回多行。有没有简单的方法来阻止这种情况发生?我尝试了 不同的p.ID ,但它没有任何区别
[编辑] Criteria API会更适合这个吗?[/ Edit]
答案 0 :(得分:3)
看起来你只是试图获得一个带有加载集合的父类列表,加上来自其他实体的一些数据,这是正确的吗?
在那种情况下:
var parents = session.CreateQuery(@"
select p, o
from Parent p, OtherClass o
join fetch p.MappedBagField
...")
.SetResultTransformer(Transformers.DistinctRootEntity)
.List<object[]>();
结果的每个项目都有两个元素,[0]是Parent,[1]是OtherClass。
答案 1 :(得分:0)
这就是Bag的语义。 Bag允许重复的实体。
而不是使用Bag(List),尝试使用Set(ISet
)。 NHibernate通常应该过滤掉重复的内容。
答案 2 :(得分:0)
使用 DISTINCT p (不包含 .ID 字段)而不是使用不同的p.ID
我遇到了重复结果行的相同问题。这解决了我的问题:
session.CreateQuery(
"SELECT DISTINCT p, o
FROM ParentClass AS p,
OtherClass AS o
INNER JOIN p.mappedBagField as bagField
WHERE ...
AND bagField.id IN (:interestingIds)")
.setParameterList("interestingIds", {1,2,3,4});
.list();
<强>解释强>
ParentClass 和 OtherClass 是两个独立的类,具有无(hibernate映射)关系。
ParentClass.mappedBagField 是第三个 hibernate映射类的集合。
在上面的例子中,我正在寻找带有 interestingIds 1,2,3和4的行。
如果 ParentClass 数据集有两个带有ids 2和4的 mappedBagField 条目,则(原始)SELECT将匹配上述 interrestingIds 两次!
这会导致两行。
将DISTINCT p添加到SELECT中会忽略重复的结果:每行只会出现一次(即使有多个 interestingId 点击)。