休眠:第二级集合中的不同结果

问题描述 投票:3回答:3

我有这样的对象模型:

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

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

我必须获取所有集合(在EntityA中的Blist和在EntityB中的CList),因为如果它们全部都需要进行某些操作,如果我不急于加载它们,则将遇到选择n + 1问题。因此查询是这样的:

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

我遇到此查询的第一个问题是,从数据库返回了重复项,因为有BList的左联接获取,所以我有EntityA重复项。快速浏览了hibernate文档,并找到了一些解决方案,首先我尝试了distinct关键字,该关键字除非某些情况下否则不会复制SQL distinct关键字,也许是其中一种情况,因为我遇到了一个SQL错误,说我无法选择离散文本列(EntityA表中的[Observations]列)。因此,我使用了其他解决方案之一:

  query.SetResultTransformer(new DistinctRootEntityResultTransformer());

这很好。但是操作结果仍然没有通过测试。我进一步检查,发现由于EntityList的左联接获取,现在存在EntityB的重复项。

问题是,如何在第二级收藏中使用非重复?我进行了搜索,但只找到根实体的直接子集合的解决方案,而从未找到第二级子集合的解决方案...

谢谢您的时间

nhibernate hql
3个回答
0
投票

您无法以简单的方式完成想要的事情。我相信是C的left join fetch导致重复。生成的查询是这样的:

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

并且数据库返回的行将是这样的:

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

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


0
投票

使用ISet而不是IList(并将其映射为固定路线,而不是袋子)。>>

集合不允许重复的实体。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.