LINQで作業しているので、LINQ-to-SQLデータコンテキストに対して正しく作業していると思いますか?私はこれをテストするために余分なDataContextを置いていませんが、これはあなたにいくつかのアイデアを与える必要があります。
私はそれがデータのコンテキストに対して動作するかどうかわかりませんが、これらのほとんどはかなり基本的なものです(連鎖OR演算子とContainsメソッド呼び出し)ので、クエリがSQLに変換されるときに問題を起こさないはずです。
Func<string, Func<DataItem, bool>> buildKeywordPredicate =
keyword =>
x => x.Title.Contains(keyword)
|| x.Contents.Contains(keyword);
これは、単一の文字列キーワードを取り、その後のDataItemを取り、キーワードに対してそれをチェックする別の関数を返す関数である:
まず私は私の述語を建設するカスタム関数を作成します。
基本的に、「スタック」を渡すと、述語:x => x.Title.Contains("Stack") || x.Contents.Contains("Stack")
が得られます。
次に、そこに多くの可能なキーワードは、あなたはOR演算でチェーンにそれを必要とするので、私はOR
Func<Func<DataItem,bool>, Func<DataItem, bool>, Func<DataItem, bool>> buildOrPredicate =
(pred1, pred2) =>
x => pred1(x) || pred2(x);
と一緒にチェーン2の述語に別のヘルパー関数を作成し、この関数は、その後2つの述語を取り、それらをOR操作で結合する。
これらの2つの機能を持って、私はそれから構築することができ、私のところこのような述語:
foreach (var word in keywords) {
filter = filter == null
? buildKeywordPredicate(word)
: buildOrPredicate(filter, buildKeywordPredicate(word));
}
フィルタがnullの場合、ループ内の最初の行は基本的にチェックします。そうであれば、簡単なキーワードフィルタが必要です。
フィルタがnullでない場合、OR演算を使用して既存のフィルタを連結する必要があるため、既存のフィルタと新しいキーワードフィルタをbuildOrPredicateに渡してその処理を行います。
そして、我々は今、クエリのWHEREの部分を作成することができます。
私達はちょうど構築した複雑な述語を渡す
var result = data.Where(filter);
。
これはPredicateBuilderを使用した場合とは異なりますが、我々はLINQツーSQLエンジンにクエリの翻訳を延期しているので、何か問題があってはならない場合、私は知りません。
しかし、私が言ったように、私は実際のデータコンテキストに対してそれをテストしていないので、問題があればコメントに書き込むことができます。
は、ここで私がテストに構築されたコンソールアプリケーションです:http://pastebin.com/feb8cc1e
は、この情報がお役に立てば幸い!
EDIT:適切にLINQで式ツリーを利用含まれ、より汎用的かつ再利用可能なバージョンについては、トーマスPetricekのブログ記事をチェックアウト:http://tomasp.net/articles/dynamic-linq-queries.aspx
これは生憎のみの機能のために動作します。これをExpression Treesで動作させるには、次のようなトリックを使用する必要があります:http://tomasp.net/articles/dynamic-linq-queries.aspx –
これはあなたがそこでやったことです!とにかく、私は今あなたのブログの購読者です:-) – chakrit
ありがとう、これは働いた。 http://tomasp.net/articles/dynamic-linq-queries.aspx - Tomas Petricek – Amir