2015-06-20 7 views
5

In meinem C# -Code muss ich zwei Nicht-Null-Variablen auswerten. Ich habe eine Reihe von if-else wenn Aussagen ausgearbeitet, aber in meinen Augen sieht es hässlich und ein bisschen zu schlampig, auch wenn es korrekt ist.Gibt es eine effiziente Möglichkeit, eine Auswahlanweisung mit zwei Variablen auszuführen?

Ich schaute in der MSDN Library und sah nur Beispiele für die Auswahl basierend auf einer einzelnen Variablen.

Gibt es eine sauberere und kompaktere Methode, um dasselbe Ergebnis zu erzielen?

Update: Ich füllte Code, um mehr Kontext zur Verfügung zu stellen. Wenn ich dies genauer betrachte, kann ich vielleicht die linq-Abfrage direkt basierend auf den Parametern manipulieren. Allerdings stelle ich die Frage die generische, auf die ich mich konzentrieren möchte: die Auswahl eher als der Code, der nach der Auswahl verwendet wird.

public ActionResult Index(string searchBy, string orderBy, string orderDir) 
{ 
    var query = fca.GetResultsByFilter(searchBy); 

    if (orderBy == "Campus" && orderDir == "Asc") 
    { 
     query = query = query.OrderBy(s => s.Campus).ThenBy(s => s.Student_Name); 
    } 
    else if (orderBy == "Campus" && orderDir == "Desc") 
    { 
    query = query.OrderByDescending(s => s.Campus); 
    } 
    else if (orderBy == "Student Name" && orderDir == "Asc") 
    { 
     query = query = query.OrderBy(s => s.Student_Name); 
    } 
    else if (orderBy == "Student Name" && orderDir == "Desc") 
    { 
     query = query.OrderByDescending(s => s.Student_Name); 
    } 
    else if (orderBy == "Course Count" && orderDir == "Asc") 
    { 
    query = query.OrderBy(s => s.Course_Count); 
    } 
    else if (orderBy == "Course Count" && orderDir == "Desc") 
    { 
    query = query.OrderByDescending(s => s.Course_Count); 
    } 
} 
+1

Was ist der '/ * ... Code ... * /'? Sie können LINQ verwenden, um solche Abfragen durchzuführen, wenn Sie davon ausgehen, dass dies der Code ist. – Cyral

+0

Ich sprach in einem allgemeineren Sinne. Dies sind Parameter, die durch eine Formularübergabe an die Funktion gesendet werden. Ich werde meine gepostete Frage ändern, um diesen Kontext bereitzustellen. –

+0

Sie könnten zuerst eine Methode wie If erstellen (check ("campus", "ASC")) ..., dann fügen Sie Ihre Strings in ein Array ein und durchlaufen ... für (i ...) {if (check (strby [i], strdir [i]))} .... oder erstelle ein spezielles Objekt dafür, wenn du zwei Arrays nicht magst ... – ElDuderino

Antwort

4

Sie könnten eine Erweiterungsmethode auf IQueryable erstellen, die entweder mit OrderBy oder OrderByDescending Griffen Bestellung:

public static class QueryableExtensions 
{ 
    public static IOrderedQueryable<TSource> OrderByWithDirection<TSource,TKey> 
     (this IQueryable<TSource> source, 
     Expression<Func<TSource, TKey>> keySelector, 
     string orderDir) 
    { 
     return orderDir == "Desc" 
         ? source.OrderByDescending(keySelector) 
         : source.OrderBy(keySelector); 
    } 
} 

Ich gehe davon aus, dass Ihre GetResultsByFilter Methode ein IQueryable<> zurückkehrt. Wenn es tatsächlich einen IEnumerable<> zurückgibt, dann muss die Erweiterungsmethode einen IEnumerable<TSource> source Parameter nehmen und stattdessen einen IOrderedEnumerable<TSource> zurückgeben.

Dies kann dann verwendet werden, wie folgt:

public ActionResult Index(string searchBy, string orderBy, string orderDir) 
{ 
    var query = fca.GetResultsByFilter(searchBy); 

    switch (orderBy) 
    { 
     case "Campus": 
      query = query.OrderByWithDirection(s => s.Campus, orderDir); 
      break; 
     case "Student Name": 
      query = query.OrderByWithDirection(s => s.Student_Name, orderDir); 
      break; 
     case "Course Count": 
      query = query.OrderByWithDirection(s => s.Course_Count, orderDir); 
      break; 
    } 

    if (orderBy == "Campus" && orderDir == "Asc") 
    { 
     // The Campus Asc case was also ordered by Student_Name in the question. 
     query = query.ThenBy(s => s.Student_Name); 
    } 
} 
+0

Gute Frage GetResultsByFilter (String) ruft 'IEnumerable GetResultsByFilter (String Filter)'. Würden Sie empfehlen, dies in das Modell oder in den Controller zu legen? –

+0

@Rubix_Revenge Angenommen, dies ist eine Datenbankabfrage, wäre es besser, 'GetResultsByFilter'' 'IQueryable ' zurückgeben. Dies ermöglicht die Ausführung des 'OrderBy' auf Datenbankebene als SQL' ORDER BY' (siehe http://stackoverflow.com/q/2876616). Ich würde wahrscheinlich die "GetResultsByFilter" -Methode in den Controller setzen, wenn sie nicht in mehr als einem Controller verwendet wurde. –

+0

Ich habe IEnumerable gemacht, um mit den größeren Anforderungen der MVC View zu arbeiten. Du bringst einen guten Punkt, aber jetzt betrete ich wieder die Welt des Whack-a-Moles, wo eine Veränderung an anderen Stellen Probleme verursacht. –

1

Ich würde den ternary-Operator verwenden, um kompakter und einfacher zu lesen, so zu machen.

Dies wird auch einige der booleschen Überprüfung ausschneiden, da es keine von ihnen dupliziert.

public ActionResult Index(string searchBy, string orderBy, string orderDir) 
    { 
     var query = fca.GetResultsByFilter(searchBy); 

     if (orderBy == "Campus") 
     { 
      query = (orderDir == "Asc") ? query.OrderBy(s => s.Campus).ThenBy(s => s.Student_Name) : 
       query.OrderByDescending(s => s.Campus); 
     } 
     else if (orderBy == "Student Name") 
     { 
      query = (orderDir == "Asc") ? query.OrderBy(s => s.Student_Name) : query.OrderByDescending(s => s.Student_Name); 
     } 
     else if (orderBy == "Course Count") 
     { 
      query = (orderDir == "Asc") ? query.OrderBy(s => s.Student_Name) : query.OrderByDescending(s => s.Course_Count); 
     } 
    } 
+0

Ich dachte nicht an einen ternären Operator, aber ich mag ihn . Es ist einfach zu lesen und zu erstellen, und ich kann leicht sehen, wie es jetzt funktioniert, dass ich es sehe. –

+0

Froh, zu helfen. Sie sind sehr nützlich. – deathismyfriend

2

CNot sicher, wenn das besser ist, nur anders.

switch (orderDir) 
{ 
    case "Asc": 
     Switch (orderBy) 
     { 
      case "Campus": 
       //Code here for Campus orderBy and Asc orderDir 
       break; 
      case "Student Name": 
       //Code here for Student Name orderBy and Asc orderDir 
       break; 
      case "Course Count": 
       //Code here for Course Count orderBy and Asc orderDir 
       break; 
     } 
     break; 
    case "Desc": 
     Switch (orderBy) 
     { 
      case "Campus": 
       //Code here for Campus orderBy and Desc orderDir 
       break; 
      case "Student Name": 
       //Code here for Student Name orderBy and Desc orderDir 
       break; 
      case "Course Count": 
       //Code here for Course Count orderBy and Desc orderDir 
       break; 
     } 
     break; 
} 
0

Meine Meinung:

public interface IOrder { 
    void perform(Query query) 
} 

public abstract class AbstractOrder : IOrder { 

    protected string orderString; 

    public AbstractOrder(string orderString) { 
     this.orderString = orderString; 
    } 
} 

public class OrderAsc { 

    public OrderAsc(string orderString) : base(orderString) { 
    } 

    public Query perform(Query query) { 
     query = query.OrderBy(s => s.Course_Count); //here you still have to do a mapping between orderString and your db field s.Course_count 
     return query; 
    } 
} 

public class OrderDesc { 

    public OrderDesc(string orderString) : base(orderString) { 
    } 

    public Query perform(Query query) { 
     query = query.OrderByDescending(s => s.Course_Count); //here you still have to do a mapping between orderString and your db field s.Course_count, or maybe it's equal, then you can just replace it. 
     return query; 
    } 
} 

dann ...

IList<IOrder> list = new List<IOrder>() {new OrderAsc("Campus"), new OrderDesc("Student Name")} 

foreach(IOrder o in list) { 
    query = o.perform(query); 
} 

Es könnte einige Fehler drin sein, ich don Habe keine IDE atm atm.

+0

Da ich immer noch auf der Sprachlernkurve bin, ist dies für mich sicherlich neu. Aber das gibt mir noch mehr Material zum Anbeißen. Vielen Dank –

Verwandte Themen