2009-09-29 9 views
6

J'essaie de trier un ensemble d'utilisateurs. J'ai accès à la propriété et à la direction de tri (asc, desc). Ma commande actuelle par requête est ci-dessous. Mais comme vous pouvez le voir, cela ne tient pas compte de la direction du tri. Comment puis-je construire cette expression sans avoir à utiliser Dynamic Linq, ou en ajoutant un autre ensemble d'instructions pour la direction de tri "asc" ou "desc".Linq Trier Direction From String

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

Répondre

12

Idéalement, vous veulent utiliser OrderByDescending - vous pourriez de tricher cours:

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

et utilisation OrderBy passant dans le sélecteur et un bool?

Si vous n'avez pas besoin du typage statique, vous pouvez également construire les expressions dynamiquement à partir de la base, bien sûr - comme this short sample (similaire à la bibliothèque dynamique LINQ).

+0

Meilleure réponse :) – Lazarus

+1

fonctionne très bien, merci. J'ai changé le bool pour utiliser System.ComponentModel.ListSortDirection – zzz

+0

Un 'IBindingList' /' IBindingListView', alors? –

2

Ce serait une déclaration si je pense, pas d'autre moyen simple de le faire, à savoir:

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

Jetez un oeil à cela aussi: Sorting a list using Lambda/Linq to objects

0

Jetez un coup d'œil aux échantillons de code CS. Il y a des exemples dynamiques de Linq.

A partir des échantillons:

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)"); 

Trier par code:

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

Mais assurez-vous que vous vérifiez l'entrée de l'utilisateur!

Questions connexes