Search code examples
c#.netnhibernatequeryovernhibernate-criteria

NH QueryOver - use properties of main query in subquery


I am trying to convert following SQL to QueryOver:

Select 1 
From myTable mt 
Where mt.ForeignKey in (select ID from otherTable ot where ot.ID = R.ID)

I want to use this subquery inside an EXISTS / NOT EXISTS statement like:

select * from table R where .... AND EXISTS (query above)

Currently I have something like:

mainQuery.WithSubquery.WhereExists(QueryOver.Of<myTable>()
                    .Where(mt => mt.ForeignKey)
                    .WithSubquery.IsIn(QueryOver.Of<otherTable>().Where(c => c.Id == R.SomeId)));

I created this query as a subquery which I want to connect to the main query. The problem is that the table aliased as R is the table called by the main query and I don´t know how to access columns of the table (NHibernate Model) R (which is not accesible in the query above), so my question is:

How can I get values from the main query and use them in a subquery. I think this is only possible by creating the subquery inline (as in mainQuery.WithSubquery.Where(..) or smth. similar) but I can´t see what would be the best possible way to do so. I appreciate any help!

Thanks in advance!


Solution

  • The trick is to use proper alias, for the parent query:

    // the alias
    myTable R = null;
    
    mainQuery
        .WithSubquery
           .WhereExists(QueryOver
             .Of<myTable>( () => R) // the Alias in place
             .Where(mt => mt.ForeignKey)
             .WithSubquery.IsIn(QueryOver.Of<otherTable>().Where(c => c.Id == R.SomeId)));
    

    Note, not fully sure about the mainQuery part, but the solution in general here is like this:

    // I. the outer query ALIAS
    Employee emplyoee = null;
    
    // II. the subquery - using the alias
    var subQuery = QueryOver.Of<Contact>()
        .Select(x => x.ID)
        .Where(x => x.Related.ID == emplyoee.ID); // use alias
    
    // III. declare the outer query and use the above alias
    var query = session.QueryOver<Employee>(() => emplyoee) // declare alias
        .WithSubquery
            .WhereExists(subQuery); // put both together
    

    Also check this for more ideas