2009-03-10 5 views
64

Я работаю с запросом LINQ to SQL и столкнулся с проблемой, когда у меня есть 4 необязательных поля для фильтрации результата данных. По выбору, я имею в виду, имеет ли выбор ввести значение или нет. В частности, несколько текстовых полей, которые могут иметь значение или быть пустой строкой и несколько раскрывающихся списков, которые могли бы иметь значение, выбранное или, может быть, не ...LINQ to SQL Where Clause Необязательные критерии

Например:

using (TagsModelDataContext db = new TagsModelDataContext()) 
    { 
     var query = from tags in db.TagsHeaders 
        where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
        && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE 
        && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE 
        select tags; 
     this.Results = query.ToADOTable(rec => new object[] { query }); 
    } 

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

  1. Номер продукта - Поставляется из другой таблицы, которая может быть соединена с тегамиHeaders.
  2. Номер заказа - поле в таблице теговHeaders.
  3. Номер для заказа - аналогично PO #, только другая колонка.
  4. Состояние продукта. Если пользователь выбрал это из раскрывающегося списка, необходимо применить выбранное значение здесь.

Запрос, который у меня уже есть, отлично работает, но для завершения функции необходимо иметь возможность добавлять эти 4 других элемента в предложение where, просто не знаете, как это сделать!

+1

Проверьте здесь Роско, это возможно, уже был дан ответ. [http://stackoverflow.com/questions/11194/conditional-linq-queries](http://stackoverflow.com/questions/11194/conditional-linq-queries) – jlembke

ответ

114

Вы можете закодировать исходный запрос:

var query = from tags in db.TagsHeaders 
       where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
       && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE 
       && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE 
       select tags; 

А потом на основе состояния, добавить дополнительные где ограничения.

if(condition) 
    query = query.Where(i => i.PONumber == "ABC"); 

Я не уверен, как закодировать это с помощью синтаксиса запроса, но id работает с лямбдой. Также работает с синтаксисом запроса для исходного запроса и лямбда для вторичного фильтра.

Вы также можете включить метод расширения (ниже), который я закодировал некоторое время назад, чтобы включить условие, в котором содержатся инструкции. (Не очень хорошо работает с синтаксисом запросов):

 var query = db.TagsHeaders 
      .Where(tags => tags.CST.Equals(this.SelectedCust.CustCode.ToUpper())) 
      .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE) 
      .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE) 
      .WhereIf(condition1, tags => tags.PONumber == "ABC") 
      .WhereIf(condition2, tags => tags.XYZ > 123); 

Метод расширения:

public static IQueryable<TSource> WhereIf<TSource>(
    this IQueryable<TSource> source, bool condition, 
    Expression<Func<TSource, bool>> predicate) 
{ 
    if (condition) 
     return source.Where(predicate); 
    else 
     return source; 
} 

Вот тот же метод расширения для IEnumerables:

public static IEnumerable<TSource> WhereIf<TSource>(
    this IEnumerable<TSource> source, bool condition, 
    Func<TSource, bool> predicate) 
{ 
    if (condition) 
     return source.Where(predicate); 
    else 
     return source; 
} 
+1

+1 Это действительно очищает код и улучшает общение – jlembke

+3

+10 Большое спасибо за ответ. Только то, что я смотрел. Я очень ценю, что вы тратите время на это. – RSolberg

+0

Нет проблем. Мне нравятся такие вещи. – andleer

26

Просто нужно использовать условную проверку для существования параметра. Например:

where (string.IsNullOrEmpty(ProductNumber) || ProductNumber == tags.productNumber) 

Таким образом, если количество продукта не вводится, что выражение возвращает истину во всех случаях, но если он введен он будет возвращать истину лишь при совпадении.

+0

+1 Это хороший.Я пытался думать о чем-то подобном ранее. – jlembke

+0

+1 Я пытался найти элегантное решение для «условного», где в моем случае у меня было несколько объединений и результат возвращал записи из объединенной таблицы. Работал как шарм! – AidaM