2009-09-29 22 views
6

Sto tentando di ordinare un set di utenti. Ho accesso alla proprietà e alla direzione di smistamento (asc, desc). Il mio ordine corrente per query è sotto. Ma come puoi vedere, non tiene conto della direzione del tipo. Come posso creare questa espressione senza dover utilizzare Dynamic Linq o aggiungere un altro insieme di istruzioni per la direzione di ordinamento "asc" o "desc".Direzione ordinamento Linq da stringa

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

risposta

12

Idealmente, si desidera utilizzare OrderByDescending - si potrebbe naturalmente imbroglio:

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

E l'uso OrderBy passando nel selettore e un bool?

Se non si ha bisogno della tipizzazione statica, è anche possibile creare dinamicamente le espressioni da zero, ovviamente - come this short sample (simile alla libreria LINQ dinamica).

+0

Risposta migliore :) – Lazarus

+1

funziona benissimo, grazie. Ho cambiato il bool per usare System.ComponentModel.ListSortDirection – zzz

+0

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

2

Sarebbe un'istruzione if credo, nessun altro modo semplice per farlo, vale a dire:

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

Date un'occhiata a questo così: Sorting a list using Lambda/Linq to objects

0

Dai un'occhiata agli esempi di codice CS. Esistono degli esempi dinamici di Linq.

Dai campioni:

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

Ordina per Codice:

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

Ma essere sicuri di controllare l'input dell'utente!

Problemi correlati