如何在父母没有重复的祖父母的情况下急切地加载几个属性(包括父/祖父母/祖父母属性)

时间:2014-03-10 16:00:01

标签: c# nhibernate

我有一个我想要加载的对象,我想急切地加载几个父元素,还有一些祖父元素。我已经设置了我的选择:

var events = (from ed in eventRepo._session.Query<EventData>() where idsAsList.Contains(ed.Id) select ed)
                            .FetchMany(ed => ed.Parents)
                            .ThenFetchMany(pa => pa.Grandparents)
                            .ThenFetch(gp => gp.GreatGrandparents)
                            // other fetches here for other attributes
                            .ToList();

我的问题是,如果我只是.FetchMany父母,我会得到正确数量的元素。一旦我加上祖父母,我就会变得太多,而且对于曾经的祖父母来说,这种情况会变得更多。

它显然正在做某种笛卡尔产品,所以我环顾四周,发现有些人使用变形金刚来解决这个问题。我看了一下并尝试实现它,但添加.TransformUsing()会导致编译器错误,因为我似乎无法在此类调用上调用.TransformUsing()

从这样的调用中获取正确数量的元素的正确方法是什么,由于计算笛卡尔积而没有重复?

2 个答案:

答案 0 :(得分:0)

这是一个非常受欢迎的帖子,它使用Futures来做这种类型的负载以避免笛卡尔产品。它不像在单个查询中那样优雅,但它可以完成工作。

Fighting cartesian product (x-join) when using NHibernate 3.0.0

另一种可能的解决方案是将您的集合定义为集合而不是行李。这也可以避免笛卡尔产品问题。我不太喜欢这个解决方案,因为你必须使用nhibernate特定的集合类型,但它已知可以工作。

答案 1 :(得分:0)

如果明确强制NHibernate连接,那么你可以做的事情就不多了。数据库将多次返回相同的实体(这是完全正常的,因为您的查询进行了笛卡尔连接)。如果您多次询问同一项目,NHibernate无法区分。 NHibernate不知道你的意图。但有一个解决方法。您可以添加以下行

var eventsSet = new HashSet<Events>(events);

假设您的实体覆盖了Equals和GetHashCode,您将获得唯一的事件。