Search code examples
nhibernatequeryover

How to do subqueries in nhibernate?


I need to do a subquery on a sub collection but I can't get it to work.

I tried this

 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();

Yet I get

Cannot use subqueries on a criteria without a projection.


Solution

  • 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>();
    

    or if you only want the completedtask then just...

    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>();
    

    or look into setting up a student filter on the Task.CompletedTasks collection. I've never used this feature before. I believe you have to enable the filter and set the student parameter before you run the query. Then your Task object would only contain completedTasks by that student...

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