2009-05-11 31 views
46

ダイナミックWHERE句をLINQステートメントにアセンブルする最適な方法は何ですか?LINQの動的WHERE句

私は、フォーム上に数十のチェックボックスを持っていると、それらをバック渡しています:辞書<文字列、私のLINQクエリの一覧<文字列> >(辞書< fieldNameを、一覧<値> >)。

public IOrderedQueryable<ProductDetail> GetProductList(string productGroupName, string productTypeName, Dictionary<string,List<string>> filterDictionary) 
{ 
    var q = from c in db.ProductDetail 
      where c.ProductGroupName == productGroupName && c.ProductTypeName == productTypeName 
      // insert dynamic filter here 
      orderby c.ProductTypeName 
      select c; 
    return q; 
} 

答えて

49

alt text http://www.scottgu.com/blogposts/dynquery/step2.png

あなたはこのようなものが必要? the Linq Dynamic Query Libraryを使用してください(ダウンロードには例が含まれています)。

は、より多くの例についてScottGu's blogをチェックしてください。

+0

github(https://github.com/kahanu/System.Linq.Dynamic)に移植されたバージョンがあります。これは私が貢献して管理するのに役立ちます。 –

8

あなたのコラムはあなたがどれ()拡張メソッドを使用することができます文字列

のような単純なタイプの
public static IEnumerable<MyObject> WhereQuery(IEnumerable<MyObject> source, string columnName, string propertyValue) 
{ 
    return source.Where(m => { return m.GetType().GetProperty(columnName).GetValue(m, null).ToString().StartsWith(propertyValue); }); 
} 
1

であれば、単純なアプローチすることができます。以下は私のために働くようです。

XStreamingElement root = new XStreamingElement("Results", 
       from el in StreamProductItem(file) 
       where fieldsToSearch.Any(s => el.Element(s) != null && el.Element(s).Value.Contains(searchTerm)) 
       select fieldsToReturn.Select(r => (r == "product") ? el : el.Element(r)) 
      ); 
      Console.WriteLine(root.ToString()); 

ここで、 'fieldsToSearch'と 'fieldsToReturn'は両方ともListオブジェクトです。

1

CodePlexのこのプロジェクトには、あなたが望むものがあります。

System.Linq.Dynamicからhttp://dynamiclinq.codeplex.com/

プロジェクトの説明

Entity Frameworkのか、任意のプロバイダに対して、文字列で定義されたラムダ式の実行をサポートするためにSystem.Linq.Dynamicを拡張IQueryableをサポートします。

それはあなたがそれはあなたがこのようなことを行うことができますScott Guthrie's Blogに見つけることができるソースコードの拡張であるとして:

enter image description here

そして、このようなこと:

enter image description here

3

私は理解することもできる解決策を思いつきました...「Contains」メソッドを使用することで、好き。 WHEREが空の文字列の場合、無視されます(またはselect allとして評価されます)。ここでは、LINQで2つのテーブルを結合し、複数のwhere節を適用し、ビューに返されるモデルクラスを設定する例を示します。 (これはすべて選択です)。

public ActionResult Index() 
    { 
     string AssetGroupCode = ""; 
     string StatusCode = ""; 
     string SearchString = ""; 

     var mdl = from a in _db.Assets 
        join t in _db.Tags on a.ASSETID equals t.ASSETID 
        where a.ASSETGROUPCODE.Contains(AssetGroupCode) 
        && a.STATUSCODE.Contains(StatusCode) 
        && (
        a.PO.Contains(SearchString) 
        || a.MODEL.Contains(SearchString) 
        || a.USERNAME.Contains(SearchString) 
        || a.LOCATION.Contains(SearchString) 
        || t.TAGNUMBER.Contains(SearchString) 
        || t.SERIALNUMBER.Contains(SearchString) 
       ) 
        select new AssetListView 
        { 
         AssetId = a.ASSETID, 
         TagId = t.TAGID, 
         PO = a.PO, 
         Model = a.MODEL, 
         UserName = a.USERNAME, 
         Location = a.LOCATION, 
         Tag = t.TAGNUMBER, 
         SerialNum = t.SERIALNUMBER 
        }; 


     return View(mdl); 
    } 
4

私はユーザー入力に基づいてフィルタを追加する必要があり、Iチェーンにwhere句を追加する必要があります。

ここにサンプルコードを示します。

var votes = db.Votes.Where(r => r.SurveyID == surveyId); 
if (fromDate != null) 
{ 
    votes = votes.Where(r => r.VoteDate.Value >= fromDate); 
} 
if (toDate != null) 
{ 
    votes = votes.Where(r => r.VoteDate.Value <= toDate); 
} 
votes = votes.Take(LimitRows).OrderByDescending(r => r.VoteDate); 
+0

私の必要性に合わせて使いやすくなっています。ありがとうございました。 – user6121177

-1

これは、誰かが興味を持っていれば私が思いついた解決策です。

https://kellyschronicles.wordpress.com/2017/12/16/dynamic-predicate-for-a-linq-query/

まず我々は(のDataRowようトロウOF)を使用し、我々が使用している「ソース」を特定の(TypedTableBaseとしてそのソース((ソースに識別子を結ぶ必要がある単一の要素タイプを識別しますTRow))。次に、渡される述語またはWHERE句(述語As Func(Of TRow、Boolean))をtrueまたはfalseとして返すかどうかを指定する必要があります。 (OrderByField As String)この関数は、述語(EnumerableRowCollection(Of TRow))の条件を満たすデータローのコレクションであるEnumerableRowCollection(Of TRow)を返します。これは基本的な例です。注文フィールドにnuが含まれていないことを確認してくださいその状況を適切に処理してカラム名を確認してください(厳密に型指定されたデータソースを使用している場合は、これを気にする必要はありません。

+0

ソリューションへのリンクは歓迎しますが、あなたの答えはそれが無ければ便利であることを確認してください:[リンクの前後にコンテキストを追加](// meta.stackexchange.com/a/8259)あなたの仲間のユーザーは、なぜそれがあるのか​​、ターゲットページが利用できない場合にリンクしているページの最も関連性の高い部分を引用します。 [リンク以上の回答は削除される可能性があります。](// stackoverflow.com/help/deleted-answers) – FelixSFD

+0

謝罪します。私はここでは新人です。 – KJM