2010-11-18 13 views
2

"コマンド"と "状態"を含むデータベーステーブルがあります。各コマンドはいくつかの状態を持つことができ、ユーザは検索時にこれを設定することができます。例えば、コマンドは「実行」であり、「高速」と「低速」の2つの状態を有することができる。linq-to-sqlヘルプを使用した高度なデータベース検索

"高速"または "低速"で "実行"と呼ばれるすべてのコマンドのテーブルを検索したいと思います。

var results = from t in table 
       where t.Command == "Run" && 
       (t.State == "Fast" || t.State == "Slow") 
       return t; 

ユーザーはまた、状態「高速」でコマンド「ウォーク」を検索することができますが、そのためのクエリは次のようになります:これは何をする非常に簡単です

var results = from t in table 
        where (t.Command == "Run" && 
         (t.State == "Fast" || t.State == "Slow")) || 
        (t.Command == "Walk" && 
        t.State == "Fast") 
        return t; 

の可能性がありますこのように多くの検索を行うことができますし、それらを一種のループでどのように組み合わせるのかと思います。

私はこれを行うことはできません:「歩く」それは「ファイル名を指定して実行」を検索したら、「ウォーク」そうを求めた結果から除外されるだろう

foreach(var command in commands) 
{ 
    foreach(var state in command.states) 
    { 
     results = from t in table 
        where t.Command == command.Command && 
        t.State == state; 
    } 
} 

ので、全く結果になるでしょう。

これを行うには良い方法がありますか?

答えて

7

利用ジョーAlbahariのPredicateBuilder述語を構築するために:

var predicate = PredicateBuilder.False<Entry>(); 
foreach(var command in commands) 
{ 
    foreach(var state in command.states) 
    { 
     predicate = predicate.Or(p => p.Command == command.Command && p.State == state); 
    } 
} 
var query = table.Where(predicate); 

以上のLINQ-重いバージョン:

var commandStates = from c in commands 
        from s in c.states 
        select new {c.Command, State = s}; 
var predicate = commandStates.Aggregate(
    PredicateBuilder.False<Entry>(), 
    (pred, e) => pred.Or(p => p.Command == e.Command && p.State == e.state)); 
var query = table.Where(predicate); 
+0

1スナップ - ほとんど:) –

+0

これは実際には非常にタイムリーです(述語ビルダー)私は後半の集約に沿ってぎこちなくなったので、どこで節を見つけましたか?あなたの成功はどのようにそれと結びついていますか? –

+0

@ジム:私は実際にまだそれの必要性を持っていませんでした。私たちがやっていることの大部分は、それを必要としないほど単純なものか、あるいは、とにかく手で完全な表現木を構築しなければならないほど高度なものです。 PredicateBuilderを使用している場合は、一般的にLinqKitを見たいかもしれません。述語やものを呼び出すための便利な機能がいくつかあります。 – StriplingWarrior

関連する問題