我有这个
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
因此任务可以有许多personalTaskReminders。我发现如果我设置2个personalTaskReminders(所以PersonalTaskReminders现在将从db中收集2行)
它返回相同的任务两次。
因此,如果我有50个personaltaskReminders用于该任务。我会得到50个相同任务的结果。我不明白为什么。
如果我删除了急切的加载。我按照预期从数据库中获取了一个任务。
答案 0 :(得分:17)
很明显,因为预先获取会导致与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>();
答案 1 :(得分:1)
Xelibrion的解决方案是解决问题的正确方法。
要了解执行Fetch
时结果重复的原因,您可以比较生成的SQL:
如果没有Fetch
SELECT
中的字段只是您的根实体Task
字段。
Fetch
PersonalReminder
个实体的字段已添加到SELECT
。因此,如果你有两个PersonalReminder
寄存器用于相同的Task
,你会在结果中得到两个寄存器,而DISTINCT
子句不会删除它们(因为实际返回的寄存器是不同的,因为它们包含PersonalReminder
字段。)
使用和不使用TransformUsing
生成的SQL完全相同,但NH处理返回的寄存器以删除重复项。