Ich habe eine Methode, die den Parameter "bool sortAscending" erhält. Jetzt möchte ich LINQ verwenden, um abhängig von diesem Parameter eine sortierte Liste zu erstellen. Ich habe dann folgendes:
var ascendingQuery = from data in dataList
orderby data.Property ascending
select data;
var descendingQuery = from data in dataList
orderby data.Property descending
select data;
Wie Sie sehen können, unterscheiden sich beide Abfragen nur in "aufsteigend" bzw. "absteigend". Ich möchte beide Abfragen zusammenführen, weiß aber nicht wie. Hat jemand die Antwort?
Antworten:
Sie können ganz einfach Ihre eigene Erweiterungsmethode für IEnumerable oder IQueryable erstellen:
public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource,TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, bool descending) { return descending ? source.OrderByDescending(keySelector) : source.OrderBy(keySelector); } public static IOrderedQueryable<TSource> OrderByWithDirection<TSource,TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool descending) { return descending ? source.OrderByDescending(keySelector) : source.OrderBy(keySelector); }
Ja, Sie verlieren hier die Möglichkeit, einen Abfrageausdruck zu verwenden - aber ehrlich gesagt glaube ich nicht, dass Sie in diesem Fall tatsächlich von einem Abfrageausdruck profitieren. Abfrageausdrücke eignen sich hervorragend für komplexe Aufgaben. Wenn Sie jedoch nur eine einzige Operation ausführen, ist es einfacher, nur diese eine Operation auszuführen:
var query = dataList.OrderByWithDirection(x => x.Property, direction);
quelle
false
für übergebendescending
.In Bezug auf die Implementierung ändert dies die Methode - von OrderBy / ThenBy zu OrderByDescending / ThenByDescending. Sie können die Sortierung jedoch separat auf die Hauptabfrage anwenden ...
var qry = from .... // or just dataList.AsEnumerable()/AsQueryable() if(sortAscending) { qry = qry.OrderBy(x=>x.Property); } else { qry = qry.OrderByDescending(x=>x.Property); }
Irgendeine Verwendung? Sie können die gesamte "Bestellung" dynamisch erstellen, dies ist jedoch aufwändiger ...
Ein weiterer Trick (hauptsächlich für LINQ-to-Objects geeignet) ist die Verwendung eines Multiplikators von -1/1. Dies ist nur für numerische Daten wirklich nützlich, aber ein frecher Weg, um das gleiche Ergebnis zu erzielen.
quelle
Was ist mit der Bestellung nach der gewünschten Eigenschaft?
Und dann so etwas tun
if (!descending) { blah = blah.Reverse() } else { // Already sorted desc ;) }
Ist es Reverse () zu langsam?
quelle
Zusätzlich zu der schönen Lösung von @Jon Skeet brauchte ich auch ThenBy und ThenByDescending, also füge ich sie basierend auf seiner Lösung hinzu:
public static IOrderedEnumerable<TSource> ThenByWithDirection<TSource, TKey>( this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, bool descending) { return descending ? source.ThenByDescending(keySelector) : source.ThenBy(keySelector); }
quelle