Search code examples
.netnhibernatequeryover

QueryOver: compare integer values from subqueries


I have to subqueries which both select an integer value:

QueryOver<Type> sq1 = QueryOver.Of<Type>().Where(someCondition)
                                          .Select(x => x.IntegerValue);
QueryOver<Type> sq2 = QueryOver.Of<Type>().Where(somethingElse)
                                          .Select(x => x.IntegerValue);

and want to Compare their results in my main query:

mainQuery.Where(Restrictions.Disjunction().Add(Subqueries.WhereValue(sq1).Le(sq2));

After adding this restriction calling mainQuery.List will result in an error where it tells me that some property does not implement IConvertible, so it seems like it won´t recognize sq1 and sq2 as int values:

"parameter value could not be converted from QueryOver`2 to Int32 (or smth similar)"


Solution

  • The idea / draft of how to achieve that should be like this:

    var sq1 = QueryOver.Of<Type>()... // we must be sure that only 1 ROW is returned
    var sq2 = QueryOver.Of<Type>()... // because it will be treated as a value
    
    // let's create IProjection
    var left  = Projections.SubQuery(sq1.DetachedCriteria);
    var right = Projections.SubQuery(sq2.DetachedCriteria);
    
    // the Restriction on top of two projections (we can use SimpleCriteria, but...
    // but this Expression can work with two projections... while named LeProperty 
    var restriction = Expression.LeProperty(left, right);
    

    and this could be passed into the main query:

    mainQuery.Where(restriction);
    

    NOTE: if we use subqueries with <= or > or = ... they must return exactly one row and one column...