2015-06-20 2 views
5

В моем коде C# мне нужно оценить две ненулевые переменные. Я разработал набор команд if-else, если, но, на мой взгляд, он выглядит уродливым и немного слишком неряшливым, даже если он правильный.Есть ли эффективный способ сделать инструкцию выбора с двумя переменными?

Я посмотрел в MSDN Library и увидел только примеры для выбора на основе одной переменной.

Есть ли более чистый и компактный способ достижения такого же результата?

Обновление: Я заполнил код, чтобы предоставить больше контекста. Глядя на это больше, возможно, я могу манипулировать linq-запросом напрямую на основе параметров. Однако вопрос, который я задаю , это общий, который я хотел бы сфокусировать на: выбор, а не код, используемый после выбора.

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

Что такое код '/ * ... ... * /'? Вы можете использовать LINQ для выполнения таких запросов, считая, что это то, что находится внутри кода. – Cyral

+0

Я говорил в более общем смысле. Эти параметры отправляются в функцию по форме submit. Я исправлю свой вопрос, чтобы предоставить этот контекст. –

+0

Вы могли бы сначала создать такой метод, как If (check ("campus", "ASC")) ..., затем добавить ваши строки в массив и выполнить цикл ... для (i ...) {if (check (strby [i], strdir [i]))} .... или создать для него специальный объект, если вам не нравятся два массива ... – ElDuderino

ответ

4

Вы можете создать метод расширения IQueryable, который обрабатывает заказ либо OrderBy или OrderByDescending:

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); 
    } 
} 

Я предполагаю, что ваш метод GetResultsByFilter возвращается в IQueryable<>. Если он действительно возвращает IEnumerable<>, то метод расширения должен будет принять параметр IEnumerable<TSource> source и вместо этого вернуть IOrderedEnumerable<TSource>.

Это может быть использована следующим образом:

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

Хороший вопрос GetResultsByFilter (string) вызывает 'IEnumerable GetResultsByFilter (строковый фильтр)'. Вы могли бы поместить это в модель или в контроллер? –

+0

@Rubix_Revenge Предполагая, что это запрос к базе данных, было бы лучше сделать 'GetResultsByFilter' return' IQueryable '. Это позволит выполнить 'OrderBy' на уровне базы данных в виде SQL' ORDER BY' (см. Http://stackoverflow.com/q/2876616). Вероятно, я бы поставил метод 'GetResultsByFilter' в контроллер, если он не использовался в нескольких контроллерах. –

+0

Я сделал IEnumerable, чтобы это работало с большими потребностями MVC View. Вы поднимаете хороший момент, но теперь я снова вхожу в мир бит-моль, где одно изменение вызывает проблемы в других местах. –

1

Я бы использовал оператор-терьер, чтобы сделать его более компактным и более удобным для чтения.

Это также вырезает некоторые булевские проверки, поскольку они не дублируют ни один из них.

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

Я не думал о тройном операторе, но мне это нравится , Его легко читать и создавать, и я могу легко увидеть, как он работает сейчас, когда я его вижу. –

+0

Рад помочь. Они очень полезны. – deathismyfriend

2

CNot уверен, что если это лучше, просто разные.

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

Мое мнение:

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; 
    } 
} 

тогда ...

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

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

Там могут быть некоторые ошибки в нем, я не У меня есть IDE под рукой.

+0

Поскольку я все еще на кривой изучения языка, это, безусловно, новичок. Но это дает мне больше материала, чтобы пережевывать. благодаря –

Смежные вопросы