2017-07-07 6 views
0

Ich arbeite derzeit an einer Anwendung in ASP.NET MVC 4.5. Ich muss eine LINQ-Abfrage schreiben, um eine Liste von Projekten nach verschiedenen Status-IDs zu sortieren.C# LINQ OrderBy mehrere Klauseln

Gegeben ist eine Liste der Projekte, die mit diesem Ansichtsmodell:

public class ProjectVm 
{ 
    public int ProjectId { get; set; } 
    public string Title { get; set; } 
    public Status StatusId { get; set; } 
} 

Mein Enum Projektstatus:

public enum Status : byte 
{ 
    Draft = 1, 
    Pending = 2, 
    Validated = 3, 
    Refused = 4 
} 

Die Idee ist es, die List<ProjectVm> in einer bestimmten Reihenfolge zu bringen, so dass durch ersten bestellt 1 Entwurf, zweite von 2 Pending, dritte von 4 abgelehnt und vierte von 3 Validiert.

Meine aktuelle Abfrage sieht wie folgt aus:

projects = projects.OrderBy(x => x.StatusId).ToList(); 

Leider ist diese Abfrage nicht die gewünschte Reihenfolge nicht einhält (4 kommt vor 3).

Wissen Sie, wie Sie eine Bedingung auf diese Abfrage anwenden, um die Projekte in die richtige Reihenfolge zu bringen (1, 2, 4, 3)?

Danke!

+0

x => ((Status) x.StatusId) .ToString()) –

+0

@ Compufreaks Comparer-Implementierung in den Antworten unten ist IMHO die beste und wiederverwendbarste und wartungsfreundlichste Methode. – JuanR

Antwort

1

Nur einige Reihenfolgen verwenden, die erste mit OrderByDescending, dann den Rest mit ThenByDescending:

projects = projects 
    .OrderByDescending(p => p.StatusId == Status.Draft) 
    .ThenByDescending(p => p.StatusId == Status.Pending) 
    .ThenByDescending(p => p.StatusId == Status.Refused) 
    .ThenByDescending(p => p.StatusId == Status.Validated) 
    .ToList(); 
-1

Versuchen Sie, diese

var projectList= projects.OrderBy(x => (int)x.StatusId).ToList(); 
+1

Dies funktioniert genauso wie ohne Int Cast. – DavidG

1

Es gibt nicht eine saubere Art und Weise es völlig inline zu tun - Sie könnte tun etwas wie:

projects.OrderBy(x => x == Status.Validated ? int.MaxValue : (int)x.StatusId) 

zu Validated zwingen, am Ende zu sein, aber ich würde eine Funktion schreiben:

private int CustomOrder(Status status) 
{ 
    switch(status) 
    { 
     // force Validated to the end 
     case Status.Validated: 
      return int.MaxValue; 
     default: 
      return (int)status; 
    } 
} 

und nenne es aus der Abfrage:

projects.OrderBy(x => CustomOrder(x)) 

Da Sie Kommentare hinzufügen und den Code organisieren zu machen es ist klarer, was deine Absicht ist.

wäre eine weitere Option, um die Werte in einem Array in der Reihenfolge Sie wollen, um in der Anordnung durch ihre Position dann zu setzen:

Status[] order = new [] {Draft, Pending, Refused, Validated}; 

projects.OrderBy(x => Array.IndexOf(order,x)); 
1

Try this:

public static int MyCustomOrder (Status status) 
{ 
    switch (status) 
    { 
     case Status.Draft  : return 1; 
     case Status.Pending : return 2; 
     case Status.Validated : return 4; 
     case Status.Refused : return 3; 

     default: return -1; 
    } 
} 

Und jetzt:

1

Nicht wirklich hübsch, aber sollte funktionieren:

projects.OrderBy(x => x.StatusId).ThenBy(c => c.StatusId == Status.Validated ? 1 : 0).ToList(); 

Andernfalls müssen Sie Ihre eigene Comparer bieten:

class StatusComparer : IComparer<Status> 
     { 
      public int Compare(Status x, Status y) 
      { 
       if (x.Equals(y)) return 0; 
       return (x > y || x.Equals(Status.Validated)) ? 1 : -1; 
      } 
     } 

Und dann rufen:

projects.OrderBy(x => x.StatusId, new StatusComparer()).ToList(); 

Oder so etwas wie die anderen Menschen hier vorgeschlagen;)

1
projects.OrderBy(x => x.StatusId == Status.Validated).ThenBy(x => x.StatusId) 

Fügt am Ende alle ausstehenden Daten ein und sortiert sie dann nach StatusID. Zwei einfache Operationen und wahrscheinlich von jedem Anbieter gut verarbeitet werden.

projects.OrderBy(x => x.StatusId == Status.Validated ? int.MaxValue : (int)x.StatusId) 

Eine einzige Operation, die daher wahrscheinlich schneller ist, dass Wieder ordnet die 3 für Pending zu int.MaxValue vor dem sortieren.

Ich würde versuchen, die zweite zuerst als wahrscheinlich effizienter, aber die zweite ist es wert, als eine allgemeine Vorgehensweise zu beachten.

+0

Sie meinen wahrscheinlich Validated statt Pending. –

+0

@DanDumitru Ich tat, danke. –