2009-09-29 11 views
6

Estoy tratando de ordenar un conjunto de usuarios. Tengo acceso a la propiedad y dirección de clasificación (asc, desc). Mi orden actual por consulta está debajo. Pero como puede ver, no tiene en cuenta la dirección de clasificación. ¿Cómo puedo construir esta expresión sin tener que utilizar Dynamic Linq, o agregar otro conjunto de instrucciones para la dirección de ordenación "asc" o "desc".Linq Dirección de clasificación de la cadena

public override IQueryable<DalLinq.User> GetSort(IQueryable<DalLinq.User> query) 
{ 
    //SelectArgs.SortDirection <- Sort Direction 
    switch (SelectArgs.SortProperty) 
    { 
     case "LastName": 
     query = query.OrderBy(p => p.LastName); 
     break; 
     case "FirstName": 
     query = query.OrderBy(p => p.FirstName); 
     break; 
     default: 
     query = query.OrderBy(p => p.UserName); 
     break; 
    } 

    return query; 
} 

Respuesta

12

Idealmente, desee utilizar OrderByDescending - que podría, por supuesto tramposo:

public static class MyExtensionMethods 
{ 
    public static IOrderedQueryable<TSource> OrderBy<TSource,TValue>(
     this IQueryable<TSource> source, 
     Expression<Func<TSource,TValue>> selector, 
     bool asc) 
    { 
     return asc ? source.OrderBy(selector) : source.OrderByDescending(selector); 
    } 
} 

Y el uso OrderBy pasando el selector y un bool?

Si no necesita el tipado estático, también puede construir las expresiones dinámicamente desde cero, por supuesto, como this short sample (similar en naturaleza a la biblioteca dinámica LINQ).

+0

Nicer respuesta :) – Lazarus

+1

funciona muy bien, gracias. Cambié el bool para usar System.ComponentModel.ListSortDirection – zzz

+0

¿Una 'IBindingList' /' IBindingListView', entonces? –

2

Sería una sentencia if creo, no hay otra forma sencilla de hacerlo, es decir:

query = (SelectArgs.SortDirection == "asc") ? query.OrderBy(p => p.LastName) 
      : query.OrderByDescending(p => p.LastName); 

Tener un vistazo a esto, así: Sorting a list using Lambda/Linq to objects

0

Eche un vistazo a las muestras de código CS. Hay ejemplos dinámicos de Linq.

partir de las muestras:

Northwind db = new Northwind(connString); 
db.Log = Console.Out; 

var query = 
    db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10). 
    OrderBy("CompanyName"). 
    Select("New(CompanyName as Name, Phone)"); 

Ordenar por Código:

public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values) { 
     return (IQueryable<T>)OrderBy((IQueryable)source, ordering, values); 
    } 

    public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) { 
     if (source == null) throw new ArgumentNullException("source"); 
     if (ordering == null) throw new ArgumentNullException("ordering"); 
     ParameterExpression[] parameters = new ParameterExpression[] { 
      Expression.Parameter(source.ElementType, "") }; 
     ExpressionParser parser = new ExpressionParser(parameters, ordering, values); 
     IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering(); 
     Expression queryExpr = source.Expression; 
     string methodAsc = "OrderBy"; 
     string methodDesc = "OrderByDescending"; 
     foreach (DynamicOrdering o in orderings) { 
      queryExpr = Expression.Call(
       typeof(Queryable), o.Ascending ? methodAsc : methodDesc, 
       new Type[] { source.ElementType, o.Selector.Type }, 
       queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters))); 
      methodAsc = "ThenBy"; 
      methodDesc = "ThenByDescending"; 
     } 
     return source.Provider.CreateQuery(queryExpr); 
    } 

Pero asegúrese de que compruebe la entrada de usuario!

Cuestiones relacionadas