Search code examples
c#nhibernatequeryovernhibernate-criteria

Nhibernate migrate ICriteria to QueryOver


We are using ICriteria and now we would like to switch to more readable QueryOver in Nhibernate

Can someone give me a hint how to convert this generic pagination logic for Icriteria to QueryOver?

public static PagedList<T> PagedList<T>(this ICriteria criteria, 
    ISession session, int pageIndex, int pageSize) where T : class
{
    if (pageIndex < 0)
        pageIndex = 0;

    var countCrit = (ICriteria)criteria.Clone();
    countCrit.ClearOrders(); // so we don’t have missing group by exceptions

    var results = session.CreateMultiCriteria()
        .Add<long>(countCrit.SetProjection(Projections.RowCountInt64()))
        .Add<T>(criteria.SetFirstResult(pageIndex * pageSize).SetMaxResults(pageSize))
        .List();

    var totalCount = ((IList<long>)results[0])[0];

    return new PagedList<T>((IList<T>)results[1], totalCount, pageIndex, pageSize);
}

Solution

  • The way I am using it:

    var session = ... // get a ISession
    
    // the QueryOver
    var query = session.QueryOver<MyEntity>();
    // apply all filtering, sorting...
    query...
    
    // GET A ROW COUNT query (ICriteria)
    var rowCount = CriteriaTransformer.TransformToRowCount(query.UnderlyingCriteria);
    
    // ask for a list, but with a Future, to combine both in one SQL statement
    var list = query
        .Future<MyEntity>()
        .ToList();
    
    // execute the main and count query at once
    var count = rowCount
        .FutureValue<int>()
        .Value;
    
    // list is now in memory, ready to be used
    var list = futureList
        .ToList();
    

    So, we are using QueryOver, and profiting from underlying criteria and transformer. With a Future, we also execute that all at one command.