2011-04-23 16 views
11

Estoy creando una prueba de concepto que utiliza Lambda/LINQ para dynamic order y orderby. El siguiente código funciona para la expresión where, pero no puedo entender cómo crear una orden por expresión. Para este ejemplo, si es posible, me gustaría mantenerlo simple; Preferiría no escribir código que modifique un Árbol de Expresión.Crear un OrderBy Expression para LINQ/Lambda

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(); 
} 

Lo que quiero es similar a lo siguiente, pero no puedo encontrar el código para crear el orden por expresión.

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(); 
} 

Si se lo está pensando, estoy utilizando LinqPad para esta prueba de concepto.

Respuesta

17
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(); 
} 

Si nos fijamos en el método de extensión OrdenarPor Acepta una Expression<Func<T, TOrderBy>> debido a que la expresión puede dar lugar a cualquier tipo dependiendo

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

Así que para ello el método de envoltura tiene que ser capaz de aceptar ese tipo genérico para pasar . en

+0

Gracias por la respuesta, pero ¿cómo hago referencia a TOrderBy? –

+0

No, lo usa el parámetro orderBy. 'Expression > orderBy' –

+1

Para ayudar a otros. Para crear la expresión orderBy, haga algo como 'Expression > orderBy = d => d.Price;'. Donde Price es un tipo decimal. En el código anterior, el decimal puede ser de cualquier tipo, como DateTime, string o int. Este tipo debe coincidir con el tipo devuelto por la expresión. Si se usa DateTime, entonces la expresión lambda debería ser algo así como d.CreatedDate. –

12

lo que busca es:

Expression<Func<Products, dynamic>>; 

intente crear una estructura/clase para contener tanto la Expresión como si es ascendente o descendente.