Search code examples
c#.netentity-framework-6expression-treesiqueryable

Chaining IQueryable expression trees


I want to be able to add ordering to my queries dynamically:

Expression<Func<IQueryable<MyEntity>, IOrderedQueryable<MyEntity>>> order1 = e => e.OrderBy(x => x.Weight);
Expression<Func<IQueryable<MyEntity>, IOrderedQueryable<MyEntity>>> order2 = e => e.OrderByDescending(x => x.Weight).ThenBy(x => x.Price);
Expression<Func<IQueryable<MyEntity>, IOrderedQueryable<MyEntity>>> order3 = e => e.OrderBy(x => x.Category).ThenBy(x => x.Price);

IQueryable<MyEntity> query = any EF query;

var transformedQuery = query.Transform(order1/order2/order3);

How do I implement Transform() ?

public static IQueryable<T> Transform<T>(this IQueryable<T> query, Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderExpr)
{
   // ??????????????????
}

My problem is that I don't want to have 2 overloads for ascending/descending ordering. I need to apply whatever OrderBy()/OrderByDescending() expression or their combination is passed.


Solution

  • This is one case where you don't need an expression tree. Or even a helper method.

    Func<IQueryable<MyEntity>, IOrderedQueryable<MyEntity>> order = e => e.OrderBy(x => x.Weight);
    IQueryable<MyEntity> query = any EF query;
    
    var transformedQuery = order(query);
    

    This works because when order is passed in a query, it can itself call the appropriate Queryable.OrderBy overload that takes an expression tree.