在进行这样的查询时(使用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时刻...
那么如何正确地做到这一点?
更新
根据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>();
答案 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;