web-dev-qa-db-ja.com

LINQ to SQL Where句のオプションの基準

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

例えば:

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

私が既に持っているクエリはうまく機能していますが、機能を完了するには、where句にこれらの4つのアイテムを追加できる必要があります。

70
RSolberg

元のクエリをコーディングできます。

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;

そして、条件に基づいて、where制約を追加します。

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

パラメータの存在の条件チェックを使用するだけです。例えば:

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

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

31
CodeRedick

| =でORを使用できます。

このスレッドを確認してください。ナイスポインターが得られる可能性があります。 やや複雑なSQLクエリに相当するC#LINQ

0