使用Fetch时,NHibernate在子集合中返回重复对象

时间:2011-01-17 14:32:51

标签: nhibernate

在进行这样的查询时(使用Nhibernate 2.1.2):

 ICriteria criteria = session.CreateCriteria<MyRootType>()
                .SetFetchMode("ChildCollection1", FetchMode.Eager)
                .SetFetchMode("ChildCollection2", FetchMode.Eager)
                .Add(Restrictions.IdEq(id));

我以一些笛卡尔式的方式获得多个重复的对象。例如。如果ChildCollection1有3个元素,而ChildColection2有2个元素,那么我会得到ChildColection1中每个元素重复的结果,ChildColection2中的每个元素都重复!这对我而言是一个WTF时刻...

那么如何正确地做到这一点?

  • 在指定一个集合时是否仅支持使用此类SetFetchMode?
  • 我只是错误地使用它(我看过一些对结果变换器的引用,但想象这会更简单)。
  • 这是NH3中不同的东西吗?

更新

根据Felice的建议,我尝试使用DistinctRootEntity转换器,但这仍然是返回重复项。代码:

ICriteria criteria = session.CreateCriteria<MyRootType>()
                .SetFetchMode("ChildCollection1", FetchMode.Eager)
                .SetFetchMode("ChildCollection2", FetchMode.Eager)
                .Add(Restrictions.IdEq(id));

 criteria.SetResultTransformer(Transformers.DistinctRootEntity);

 return criteria.UniqueResult<MyRootType>();

5 个答案:

答案 0 :(得分:15)

您可以通过指定SetResultsTransformer(Transformers.DistinctRootEntity);

来选择单个不同的结果

答案 1 :(得分:10)

你在这里做cartesian product。别。相反,fetch each collection separately

BTW:这不是特定于NHibernate的东西,同样适用于任何平台中的任何ORM,甚至完全没有任何ORM的纯SQL。通常,当您可以获取N + M时,您不希望获取N * M行。

答案 2 :(得分:3)

我不是在使用NHibernate(而是常规的'ol Hibernate),但在Java版本的Hibernate中,您可以将一对多集合定义为列表或集合。如果将它们定义为集合,则不会重复。令人惊讶的是,这不会覆盖equals()。不幸的是,我有同样的问题,我想要列表,所以我可以与Wicket集成,但没有重复......

答案 3 :(得分:3)

您将收藏集映射为什么?例如,如果你使用包,你会得到重复。您可以使用一组而不会重复。

答案 4 :(得分:2)

尝试使用Futures

ICriteria criteriaFuture1
    = session.CreateCriteria<MyRootType>()
        .SetFetchMode("ChildCollection1", FetchMode.Eager)
        .Add(Restrictions.IdEq(id))
        .SetResultTransformer(Transformers.DistinctRootEntity)
        .FutureValue<MyRootType>();
 ICriteria criteriaFuture2
    = session.CreateCriteria<MyRootType>()
        .SetFetchMode("ChildCollection2", FetchMode.Eager)
        .Add(Restrictions.IdEq(id))
        .SetResultTransformer(Transformers.DistinctRootEntity)
        .FutureValue<MyRootType>();

 return criteriaFuture1.Value;