Come posso eseguire un ordine con un parametro di stringa dinamico?

Voglio farlo:

var orderBy = "Nome, Cognome desc"; var timb = time.Timbratures.Include("Anagrafica_Dipendente") .Where(p => p.CodDipendente == 1); if(orderBy != "") timb = timb.OrderBy(orderBy); 

Esiste un sovraccarico di OrderBy che accetta un parametro stringa?

Assolutamente. Puoi utilizzare la LINQ Dynamic Query Library, disponibile sul blog di Scott Guthrie . C’è anche una versione aggiornata disponibile su CodePlex .

Ti consente di creare le clausole OrderBy , le clausole Where e quasi tutto il resto passando i parametri delle stringhe. Funziona alla grande per la creazione di codice generico per l’ordinamento / filtraggio delle griglie, ecc.

 var result = data .Where(/* ... */) .Select(/* ... */) .OrderBy("Foo asc"); var query = DbContext.Data .Where(/* ... */) .Select(/* ... */) .OrderBy("Foo ascending"); 

Se si utilizza LINQ-to-object normale e non si vuole fare affidamento su una libreria esterna, non è difficile ottenere ciò che si desidera.

La clausola OrderBy() accetta Func che ottiene una chiave di ordinamento da un elemento source. È ansible definire la funzione al di fuori della clausola OrderBy() :

 Func orderByFunc = null; 

È quindi ansible assegnarlo a valori diversi in base ai criteri di ordinamento:

 if (sortOrder == SortOrder.SortByName) orderByFunc = item => item.Name; else if (sortOrder == SortOrder.SortByRank) orderByFunc = item => item.Rank; 

Quindi puoi ordinare:

 var sortedItems = items.OrderBy(orderByFunc); 

In questo esempio si presuppone che il tipo di origine sia Item con proprietà Name e Rank .

Si noti che in questo esempio TKey è Object per non vincolare i tipi di proprietà su cui è ansible ordinare. Se la funzione restituisce un tipo di valore (come Int32 ) verrà inserito nella casella quando viene ordinato e ciò è in qualche modo inefficiente. Se è ansible vincolare TKey a un tipo di valore specifico, è ansible aggirare questo problema.

Un’altra soluzione di codeConcussion ( https://stackoverflow.com/a/7265394/2793768 )

 var param = "Address"; var pi = typeof(Student).GetProperty(param); var orderByAddress = items.OrderBy(x => pi.GetValue(x, null)); 

Non hai bisogno di una libreria esterna per questo. Il codice seguente funziona per LINQ su SQL / quadro.

  ///  /// Sorts the elements of a sequence according to a key and the sort order. ///  /// The type of the elements of . /// A sequence of values to order. /// Name of the property of  by which to sort the elements. /// True for ascending order, false for descending order. /// An  whose elements are sorted according to a key and sort order. public static IQueryable OrderBy(this IQueryable query, string key, bool ascending = true) { if (string.IsNullOrWhiteSpace(key)) { return query; } var lambda = (dynamic)CreateExpression(typeof(TSource), key); return ascending ? Queryable.OrderBy(query, lambda) : Queryable.OrderByDescending(query, lambda); } private static LambdaExpression CreateExpression(Type type, string propertyName) { var param = Expression.Parameter(type, "x"); Expression body = param; foreach (var member in propertyName.Split('.')) { body = Expression.PropertyOrField(body, member); } return Expression.Lambda(body, param); } 

( CreateExpression copiata da https://stackoverflow.com/a/16208620/111438 )

La soluzione più semplice e migliore:

 mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s)); 

Guarda questo blog qui . Descrive un modo per farlo, definendo un EntitySorter .

Ti permette di passare un IEntitySorter nei tuoi metodi di servizio e usarlo in questo modo:

 public static Person[] GetAllPersons(IEntitySorter sorter) { using (var db = ContextFactory.CreateContext()) { IOrderedQueryable sortedList = sorter.Sort(db.Persons); return sortedList.ToArray(); } } 

E puoi creare un EntitiySorter questo modo:

 IEntitySorter sorter = EntitySorter .OrderBy(p => p.Name) .ThenByDescending(p => p.Id); 

O in questo modo:

 var sorter = EntitySorter .OrderByDescending("Address.City") .ThenBy("Id"); 

È necessario utilizzare la libreria di query dynamic LINQ per passare i parametri in fase di esecuzione,

Ciò consentirà istruzioni linq come

 string orderedBy = "Description"; var query = (from p in products orderby(orderedBy) select p); 

L’ho fatto:

 using System.Linq.Expressions; namespace System.Linq { public static class LinqExtensions { public static IOrderedQueryable OrderBy(this IQueryable source, string field, string dir = "asc") { // parametro => expressão var parametro = Expression.Parameter(typeof(TSource), "r"); var expressao = Expression.Property(parametro, field); var lambda = Expression.Lambda>(expressao, parametro); // r => r.AlgumaCoisa if (string.Equals(dir, "desc", StringComparison.InvariantCultureIgnoreCase)){ return source.OrderByDescending(lambda); } return source.OrderBy(lambda); } public static IOrderedQueryable ThenBy(this IOrderedQueryable source, string field, string dir = "asc") { var parametro = Expression.Parameter(typeof(TSource), "r"); var expressao = Expression.Property(parametro, field); var lambda = Expression.Lambda>(expressao, parametro); // r => r.AlgumaCoisa if (string.Equals(dir, "desc", StringComparison.InvariantCultureIgnoreCase)) { return source.ThenByDescending(lambda); } return source.ThenBy(lambda); } } } 

Uso :

 example.OrderBy("Nome", "desc").ThenBy("other") 

Funziona come:

 example.OrderByDescending(r => r.Nome).ThenBy(r => r.other) 

In una risposta sopra:

La soluzione più semplice e migliore:

 mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s)); 

C’è un errore di syntax ,null deve essere aggiunto ,null :

 mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s,null));