在NHibernate中如何执行子查询?

14

我需要在一个子集合上进行子查询,但我做不好。

我尝试了这个:

 Task tAlias = null;
        List<Task> result = session.QueryOver<Task>(() => tAlias)
                                   .Where(Restrictions.In(Projections.Property(() => tAlias.Course.Id), courseIds))
                                   .WithSubquery.WhereExists(QueryOver.Of<CompletedTask>().Where(x => x.Student.StudentId == settings.StudentId))                                     
().ToList();

然而我得到了以下错误:

无法在没有投影的条件上使用子查询。

1个回答

25
session.QueryOver<Task>(() => tAlias)
    .WhereRestrictionsOn(x => x.Course.Id).IsIn(courseIds)
    .WithSubquery.WhereExists(QueryOver.Of<CompletedTask>()
        .Where(x => x.id == tAlias.id) //not sure how you need to link Task to CompletedTask
        .Where(x => x.Student.StudentId == settings.StudentId)
        .Select(x => x.id)) //exists requires some kind of projection (i.e. select clause)
    .List<Task>();

或者,如果你只想要已完成的任务,那么只需...

Task taskAlias = null;

session.QueryOver<CompletedTask>()
    .JoinAlias(x => x.Task, () => taskAlias)
    .WhereRestrictionsOn(() => taskAlias.Course.Id).IsIn(courseIds)
    .Where(x => x.Student.StudentId == settings.StudentId)
    .List<CompletedTask>();

或者尝试设置一个基于学生的过滤器在Task.CompletedTasks集合上。我以前从未使用过这个功能,但我相信你需要在运行查询之前启用过滤器并设置学生参数。然后您的Task对象将只包含由该学生完成的已完成任务...

http://nhibernate.info/doc/nh/en/index.html#filters


@dotjoe - 我想要返回整个 Task 对象,我应该这样做吗? (x => x.Task) - chobo2
@dotjoe - 为什么我需要在id上使用where子句?为什么我需要将任务链接到已完成的任务?我只是希望查询已完成的任务,使其仅具有与学生相关的记录。 - chobo2
1
更新的答案。我认为错误只是因为WhereExists分离查询没有任何投影,即Select()。主查询可以使用List<Task>() - dotjoe
@dotjoe - 我仍然需要任务对象。完成的任务对象可能是一个集合,但如果我正确地执行子查询,它应该始终只有零或一个计数。 - chobo2
@dotjoe - 抱歉,从我发布的一个查询中尝试弄清楚所有内容可能会让人感到困惑。只要学生是该课程的一部分,我需要始终返回任务。使用您的查询,它仅返回已完成的任务。我需要显示未完成和已完成的任务。我的计划是查看已完成任务的数量是否等于1,这意味着学生已完成任务。如果为零,则表示他们没有完成。但是,无论他们是否完成,我都需要返回所有任务信息,因为那只是一个视觉上的东西(勾选标记)。 - chobo2
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接