Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an OrderBy Expression for LINQ/Lambda

Tags:

c#

lambda

linq

I'm creating a proof of concept that uses Lambda/LINQ for dynamic where and orderby. The following code works for the where expression, but I can not figure out how to create an order by expression. For this example, if possible I would like to keep it simple; I would rather not write code that modifies an Expression Tree.

void Main()
{
    DateTime productSince = DateTime.UtcNow.Subtract(new TimeSpan(1,30,0));
    Expression<Func<Products, bool>> filter = d => d.CreatedDate > productSince && d.Price < 100 ;    
    List<Products> products = GetProducts(filter, Products);
    Console.WriteLine(products);
}

private static List<Products> GetProducts(Expression<Func<Products, bool>> filter,  Table<Products> Products)
{

    var products = Products.Where(filter);
    return products.ToList();
}

What I want is similar to the following but can not figure out the code to create the order by expression.

void Main()
{
    DateTime productSince = DateTime.UtcNow.Subtract(new TimeSpan(1,30,0));
    Expression<Func<Products, bool>> filter = d => d.CreatedDate > productSince && d.Price < 100 ;
    Expression<Func<Products, ????>> orderBy = d => ??????;

    List<Products> products = GetProducts(filter, orderBy, Products);
    Console.WriteLine(products);
}

private static List<Products> GetProducts(Expression<Func<Products, bool>> filter,
               Expression<Func<Products, ???>> orderBy, Table<Products> Products)
{

    var products = Products.Where(filter).OrderBy(orderBy);
    return products.ToList();
}

If you are wondering, I'm using LinqPad for this proof of concept.

like image 293
Mike Barlow - BarDev Avatar asked Apr 23 '11 18:04

Mike Barlow - BarDev


2 Answers

private static List<Products> GetProducts<TOrderBy>(Expression<Func<Products, bool>> filter,
               Expression<Func<Products, TOrderBy>> orderBy, Table<Products> Products)
{

    var products = Products.Where(filter).OrderBy(orderBy);
    return products.ToList();
}

If you look at OrderBy extension method it accepts a Expression<Func<T, TOrderBy>> because the expression can result in any type depending

.OrderBy(x => x.ID) // <T, int>
.OrderBy(x => x.Name) // <T, string>

So therefor your wrapper method needs to be able to accept that generic type to pass in.

like image 125
Chad Moran Avatar answered Oct 04 '22 22:10

Chad Moran


what you are looking for is:

Expression<Func<Products, dynamic>>;

try create a structure/class to hold both the Expression and if it is ascending or descending.

like image 43
scotty Avatar answered Oct 04 '22 22:10

scotty