2009-03-10 27 views
64

LINQ to SQLクエリを使用しており、データ結果をフィルタリングする4つのオプションフィールドがある問題が発生しました。オプションでは、値を入力するかどうかを選択できます。具体的には、値を持っているか、空の文字列と値が選択されたか、そうでないかもしれない持っている可能性のリストダウンいくつかのドロップを持っている可能性があり、いくつかのテキストボックス...例えばLINQ to SQL Where句オプションの条件

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. 製品番号 - タグヘッダーに結合できる別のテーブルから来ます。
  2. PO Number - TagsHeadersテーブル内のフィールド。
  3. 注文番号 - PO#と同様、ちょうど異なる列。
  4. 製品ステータス - ユーザーがドロップダウンからこれを選択した場合、ここで選択した値を適用する必要があります。

私はすでに持っているクエリは素晴らしいですが、関数を完了するには、これらの4つの項目をwhere節に追加する必要があります。

+1

チェックここロスコー、それ:

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に同じ拡張メソッドでありますすでに回答されている可能性があります。 [http://stackoverflow.com/questions/11194/conditional-linq-queries](http://stackoverflow.com/questions/11194/conditional-linq-queries) – jlembke

答えて

114

:それはあなたにいくつかの素敵な指針を与える可能性があるとして

は、このスレッドをチェックしてください。

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

これはクエリ構文でどのようにコード化するのかわかりませんが、idはラムダで動作します。また、初期クエリのクエリ構文とセカンダリフィルタのラムダで動作します。

また、条件付きのwhere文を含めるために、私はしばらく前にコーディングした拡張メソッド(下記)を含めることもできます。 (クエリ構文とうまく動作しない):

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

製品番号は、式は、すべての場合にtrueを返しますが、それが入力された場合にのみ一致したときにtrueを返しますことを入力されていない場合はその方法。

+0

+1いいね同様のことを以前と同じように考えようとしていました。 – jlembke

+0

+1私は、条件付きの場所で私の場合、複数の結合と結果が結合されたテーブルからのレコードを返すという、洗練されたソリューションを見つけようとしていました。チャームのように働いた! – AidaM

0

あなたは||とORすることができます。追加の場所の制約条件を追加し、条件に基づいて

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; 

そして:あなたがあなたの元のクエリを記述することができます C# LINQ equivalent of a somewhat complex SQL query