3

我有这个

   using (ITransaction transaction = session.BeginTransaction())
        {
            Task tAlias = null;
            CompletedTask cAlias = null;

            List<Task> tasks = session.QueryOver<Task>(() => tAlias)
                .Where(Restrictions.In(Projections.Property(() => tAlias.Course.Id), courseIds))
                .Fetch(pt => pt.PersonalTaskReminders).Eager
                .List<Task>().ToList().ConvertToLocalTime(student);


            transaction.Commit();

            return tasks;
        }

    PersonalTaskReminders == Collection

所以一个任务可以有多个personalTask​​Reminder。我发现如果我设置了 2 个personalTask​​Reminders(所以 PersonalTask​​Reminders 现在将在它的数据库集合中有 2 行)

它两次返回相同的任务。

因此,如果我有 50 个用于该任务的个人任务提醒。我会得到 50 个相同任务的结果。我不明白为什么。

如果我删除急切的加载。我按预期从数据库中取回了一项任务。

4

2 回答 2

17

很明显,因为 Eager fetch 导致加入 2 个表。要消除重复的结果,您应该使用 DistinctRootEntityTransformer。

顺便说一句,NHibernate 为IN从句提供了更好的语法。所以你的查询应该是这样的:

    var tasks = Session.QueryOver<Task>()
            .WhereRestrictionOn(x => x.Id).IsIn(courseIds)
            .Fetch(pt => pt.PersonalTaskReminders).Eager
            .TransformUsing(Transformers.DistinctRootEntity)
            .List<Task>();
于 2011-06-03T07:28:05.500 回答
1

Xelibrion 的解决方案是解决问题的正确方法。

要理解为什么做的时候结果重复Fetch,可以对比一下生成的SQL:

没有Fetch中的字段SELECT只是您的根实体Task字段。

随着实体Fetch的字段PersonalReminder已添加到SELECT. 因此,如果您有两个PersonalReminder相同的寄存器,Task您会在结果中得到两个寄存器,并且DISTINCT子句不会删除它们(因为实际返回的寄存器不同,因为它们包含PersonalReminder字段)。

使用和不使用生成的 SQLTransformUsing完全相同,但 NH 会处理返回的寄存器以删除重复项。

于 2013-09-24T11:28:38.710 回答