2010-03-13 2 views
7

Я просто читал недавний вопрос на using conditionals in Linq, и это напомнило мне проблему, которую я не смог решить. При программировании Linq to SQL запрограммировать, как это можно сделать, когда количество условных выражений неизвестно до выполнения?Использование условных выражений в Linq Программно

Например, в приведенном ниже коде первое предложение создает IQueryable, который, если будет выполнен, будет выбирать все задачи (называемые проблемами) в базе данных, второе предложение будет уточнять это только для вопросов, назначенных одному отделу, если есть был выбран в combobox (у которого есть выделенный элемент, привязанный к свойству departmentToShow).

Как я могу сделать это, используя вместо него коллекцию selectedItems?

IQueryable<Issue> issuesQuery; 

// Will select all tasks 
issuesQuery = from i in db.Issues 
       orderby i.IssDueDate, i.IssUrgency 
       select i; 

// Filters out all other Departments if one is selected 
    if (departmentToShow != "All") 
    { 
     issuesQuery = from i in issuesQuery 
         where i.IssDepartment == departmentToShow 
         select i; 
    } 

Кстати, приведенный выше код упрощен, в самом коде есть около десятка статей, которые уточняют запрос на основе пользователей поиска и настройки фильтра.

ответ

7

Если число условий неизвестна, то это проще использовать лямбда-синтаксис вместо понимания запроса, то есть:

IQueryable<Issue> issues = db.Issues; 
if (departmentToShow != "All") 
{ 
    issues = issues.Where(i => i.IssDepartment == departmentToShow); 
} 
issues = issues.OrderBy(i => i.IssDueDate).ThenBy(i => i.IssUrgency); 

(Предполагая, что вы хотите, упорядоченность произойдет после фильтрации, что должно быть так - Я не уверен, что Linq будет генерировать оптимизированный запрос, если вы сначала попытаетесь выполнить заказ).

Если у вас есть очень большое количество дополнительных условий, то вы можете очистить его с предикатами:

List<Predicate<Issue>> conditions = new List<Predicate<Issue>>(); 
if (departmentToShow != "All") 
    conditions.Add(i => i.IssDepartment == departmentToShow); 
if (someOtherThing) 
    conditions.Add(anotherPredicate); 
// etc. snip adding conditions 

var issues = from i in issues 
      where conditions.All(c => c(i)) 
      orderby i.IssDueDate, i.IssUrgency; 

Или просто использовать PredicateBuilder, который, вероятно, проще.

+0

Фактически один элемент в моем списке задач - это вытащить явный порядок и добавить его в интерфейс, чтобы пользователь имел некоторый контроль. –

+0

В выражении Lambda выше, как это будет работать с departmentToShow, являющимся коллекцией из combobox, я подумал, что то, что у вас есть, точно такое же, как и у моего запроса. Должен признаться, что я новичок, и Лямбда - одна из тех вещей, которые имеют больше смысла для меня в книгах, чем на практике. –

+0

@Mike B: Он похож на то, что у вас есть, но, очевидно, менее подробный, и ваша оригинальная версия делает заказ перед вторым фильтром (вы хотите, чтобы это произошло в конце). Если 'departmentToShow' является коллекцией, тогда вы пишете' departmentToShow.Contains (i.IssDepartment) 'вместо' i.IssDepartment == departmentToShow'. – Aaronaught

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