Search code examples
c#nhibernateormqueryover

Why IQueryOver has 2 type arguments?


Why IQueryOver has 2 type arguments:

QueryOver<TRoot,TSubType> is an API for retrieving entities by composing
NHibernate.Criterion.Expression objects expressed using Lambda expression
syntax.

Solution

  • The answer is: to support fluent syntax, and have access to root settings all the time.

    not so fluent

    So we can use this definition:

    IQueryOver<Contact,Contact> rootQuery = session  // here we have Contact query
        .QueryOver<Contact>();                          
    IQueryOver<Contact, Employee> emplQueryOver = rootQuery
        .JoinQueryOver<Employee>(c => c.Parnter);       // here we work with its Parnter
    IQueryOver<Contact, Employee> creatorQueryOver = emplQueryOver
        .JoinQueryOver<Employee>(e => e.Creator);       // here we have creator of Parnter
    

    So having this, we can do some filtering:

    emplQueryOver.Where(...
    creatorQueryOver.Where(...
    

    and then go back to root query and set

    rootQuery.OrderBy(c => c.ID).Desc
        .ThenBy(c => c.LastName)
          .Asc
        .SelectList(...
        .Take(50);
    

    fluent

    But because of the interface IQueryOver<TRoot, TSubType> beeing returned all the way down, we can do that without the middle variables... we can do it in one fluent run

    var list = session  // here we have Contact query
        .QueryOver<Contact>()
           .Where(... //filter contact
        // Join Parnter
        .JoinQueryOver<Employee>(c => c.Parnter)
            .Where(... //filter Partner
        // Join More
        .JoinQueryOver<Employee>(e => e.Creator)
    
        // While still having the Root in the scope we can do
        .SelectList(list => list....
        .OrderBy(c => c.ID)
          .Desc
        .ThenBy(c => c.Code)
          .Asc
        .Take(50)
        .Skip(50)
        .List<Contact>(); // the Root