Nhibernate:二级Collection中的明显结果

时间:2010-02-07 18:39:03

标签: nhibernate hql hibernate-criteria

我有一个像这样的对象模型:

   class EntityA
   {
        ...
        IList<EntityB> BList;
        ...
   }

   class EntityB
   {
       ...
       IList<EntityC> CList;
   }

我必须获取所有的colelctions(EntityA中的Blist和EntityB中的CList),因为如果他们都需要进行一些操作,如果我不急于加载它们,我将有选择n + 1问题。 所以查询是这样的:

  select a from EntityA a left join fetch a.BList b left join fetch b.CList c

我遇到这个问题的第一个问题是从数据库返回重复项,我有EntityA重复项,因为左边的连接提取与BList。 快速阅读hibernate文档,并有一些解决方案,首先我尝试了distinct关键字,supposelly不会复制SQL distinct关键字,除了在某些情况下,也许这是其中一个案例因为我有一个SQL错误说我无法选择distict text列(EntityA表中的[Observations]列)。所以我使用了其他解决方案之一:

  query.SetResultTransformer(new DistinctRootEntityResultTransformer());

这很好用。但是操作的结果仍未通过测试。我进一步检查了一下,我发现现在有重复的EntityB,因为左边的连接提取与CList。

问题是,我如何在二级集合中使用distinct?我搜索过,我只找到根实体的直接子集合的解决方案,但从来没有为二级子集合找到...

感谢您的时间

3 个答案:

答案 0 :(得分:0)

你无法以简单的方式完成你想要的任务。我相信这是导致重复的C的左连接提取。生成的查询是这样的:

select a 
left join a.b b
left join b.c c

并且db返回的行将如下所示:

1: a1 | b1 | c1
2: a1 | b1 | c2
3: a1 | b2 | c3
4: a1 | b2 | c4
...

你已经过滤了根实体重复项( A ),由于C上的外部联接,数据库需要返回 B 每个 C 条目的表格。 解决此问题的一种简单方法是通过实用程序集合过滤项目。根据您的实体要求,您还可以使用HashSet,以便自动过滤掉它们。

答案 1 :(得分:0)

使用ISet代替IList(并将其映射为套装,而不是袋子)。

Set不允许重复的实体。

答案 2 :(得分:0)

我遇到了同样的问题,无法通过hql解决重复问题。但是,我为所有集合创建了IEqualityComparer,并在每个Collection上执行Disinct()以消除hql结果之上的重复。