2016-04-08 9 views
0

Liste auf mehrere Eigenschaften sortieren möchte ich Liste sortieren auf mehrere Eigenschaften auf. Ich weiß, ich kann verwendenWie in einer Zeile Code in Linq

List<Order> l = source.OrderBy(c=> c.Property1).ThenBy(c=> c.Property2).ToList(); 

Allerdings ist es nur für aufsteigend. Wenn ich für absteigend sortieren Liste will, muss ich einen anderen Code

List<Order> l = source.OrderByDescending(c=> c.Property1).ThenByDescending(c=> c.Property2).ToList(); 

Und wenn ich property1 für aufsteigend und property2 für absteigend sortiert werden soll, habe ich

List<Order> l = source.OrderBy(c=> c.Property1).ThenByDescending(c=> c.Property2).ToList(); 

Für Art auf 2 Objekte zu verwenden, Ich brauche 4 verschiedene Codes und bei 3 Eigenschaften brauche ich 9 verschiedene Codes. Es ist nicht gut. Ich möchte wissen, ob es eine Möglichkeit gibt, die Sortierung in einem Code zu erledigen. Vielen Dank.

+0

das ist der beste Weg, es zu tun ... –

+0

Meinst du, dass die Richtung der Sortierung parametrisiert werden soll, so dass der gleiche Code in Abhängigkeit von den Parametern in jeder Kombination von aufsteigender und absteigender Sortierung? –

+0

Ich denke, Linq bietet eine Möglichkeit, sollte Art wie zu tun: OrderBy (c => c.Property1, sortOrder) .ThenBy (c => c.Property2, sortOrder). Es ist einfach und geradlinig. Gibt es in Linq so etwas? – user585440

Antwort

1

Sie können Ihre eigene LINQ-Erweiterung, um zu bestimmen, welche Methode zu holen schreiben. Zum Beispiel:

public static class LinqExtensions 
{ 
    public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool ascending) 
    { 
     return ascending ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector); 
    } 
} 

Und dann können Sie es wie folgt verwendet werden:

source.OrderBy(a => a.Id, ascending); 
+0

Wie source.OrderBy (a => a.Id, aufsteigend) .ThenBy (c => c.name, absteigend)? Ich weiß, dass Sortierung nach verschiedenen Eigenschaften gleichzeitig erfolgen muss. – user585440

+0

@ user585440 Sie würden einfach den obigen Code kopieren und in 'ThenBy' ändern. – Rob

+0

Aber wie OrderBy und ThenBy mit "." Zu verketten? – user585440

0

Das System.Linq.Dynamic Paket bietet eine OrderBy Erweiterung Methode, die nur einen String:

using System.Linq.Dynamic; 
//...  

var l = source.OrderBy("Property1 ascending, Property2 descending").ToList(); 

können Sie verwenden es aufwendig Ausdrücke on the fly zu erstellen:

string orderByClause = string.Format("Property1 {0}, Property2 {1}", "ascending", "descending"); 
var l = source.OrderBy(orderByClause).ToList(); 

Siehe IQueryable Extension Methods für weitere Informationen im Projekt Wiki

1

Wie ich in den Kommentaren erwähnen Sie so etwas wie dieses ... es so

erstellen
public static class LinqExtension 
{ 
    public static IOrderedEnumerable<TSource> OrderByAsc<TSource, TKey>(
    this IEnumerable<TSource> source, 
    Expression<Func<T, object>> expression) 
    { 
     IEnumerable<TSource> newEnumerable = source; 
     int ctr = 0; 
     NewArrayExpression array = expression.Body as NewArrayExpression; 
     foreach(object obj in (IEnumerable<object>)(array.Expressions)) 
     { 
      if(ctr == 0) 
      newEnumerable = newEnumerable 
       .OrderBy(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null)); 
      else 
      newEnumerable = newEnumerable 
       .ThenBy(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null)); 
      ctr++; 
     } 

     return newEnumerable;  
    } 

    public static IOrderedEnumerable<TSource> OrderByDesc<TSource, TKey>(
    this IEnumerable<TSource> source, 
    Expression<Func<T, object>> expression) 
    { 
     IEnumerable<TSource> newEnumerable = source; 

     NewArrayExpression array = expression.Body as NewArrayExpression; 
     int ctr = 0; 
     foreach(object obj in (IEnumerable<object>)(array.Expressions)) 
     { 
      if(ctr == 0) 
      newEnumerable = newEnumerable 
       .OrderByDescending(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null)); 
      else 
      newEnumerable = newEnumerable 
       .ThenByDescending(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null)); 
      ctr++; 
     } 

     return newEnumerable;  
    } 
} 

und Verwendung:

using myNameSpace.LinqExtensions; 
... 

l = l.OrderByAsc(item => new [] { item.Prop1, item.Prop2, item.Prop3}); 
l = l.OrderByDesc(item => new [] { item.Prop1, item.Prop2, item.Prop3}); 

Natürlich können Sie versuchen, eine Erweiterung zu erstellen, um beide Ordnungen zu kombinieren, indem Sie auf eine einzelne Methode auf- und absteigen. Nur eine Idee.

HAFTUNGSAUSSCHLUSS: Ich schrieb dies auf Notizblock und habe es nicht aufgrund von Ressourcenmangel getestet.

Verwandte Themen