none
Linq to SQL で or 検索 RRS feed

  • 質問

  • お世話になっています。 mrt136-2 と申します。

     

    Linq用のフォーラムが無かったので、こちらにて質問させて頂きます。

     

    表題のとおりですが、Linq to SQL で条件数の不定な場合の OR 検索ってどうされますか?

    要は、ユーザが、任意にフィールドと検索条件(完全一致、部分一致、AND、OR等)を指定して

    検索させる様な処理を考えています。

     

    AND検索の場合は、

     

    var result = from hoge in hogehoge  select hoge;

     

    foreach(string keyword in keywords){

          result = from hoge in result <--- 上記の結果から絞込み

                      where hoge.text1.Contains(keyword)

                      select hoge;

    }

    result = from hoge in result <--- 上記の結果から絞込み

                where hoge.integer1 == 1

                select hoge;

     

    var result2 = result.ToList();  <--- 最後にクエリ発行

     

    の様にどんどん条件を追加していけば良いかと思うのですが、これが OR の場合は何か方法がありますでしょうか?

    とりあえず、考えたのは、以下の様に、ひとつずつ条件にヒットするリストを足していくと言う方法ですが、

    これだと、検索条件の数だけ、クエリを発行しないといけないので、あまりにも非効率ですよね。。。

     

    var result = from hoge in hogehoge  select hoge;

     

    var result2 = result.Take(0);   <---クエリ発行(これは要らない?でも、上記のselectが匿名の場合はこうしないと無理?)

     

    foreach(string keyword in keywords){

       result2 = result2.Concat((from hoge in hogehoge   <--- 元々のテーブルから抽出

                                               where hoge.text1.Contains(keyword)

                                               select hoge).ToList());  <--- 条件毎にクエリ発行

    }

     

    result2 = result2.Concat((from hoge in hogehoge   <--- 元々のテーブルから抽出

                                        where hoge.integer1 == 1

                                        select hoge).ToList());    <--- 条件毎にクエリ発行

     

    この様な処理って、一般的(?)にどのようにするのが良いのでしょうか?

    SQLを文字列で組んで、ExecuteCommand() メソッドで実行する方が良いのでしょうか。。。

     

    何か効率の良い方法があれば、ご教授頂ければ幸いです。

    よろしくお願いします。

     

     

    2008年8月21日 11:32

回答

  •  mrt136-2 さんからの引用

    AND検索の場合の foreach ですが、

     

    foreach(string keyword in keywords){

          result = from hoge in result <--- 上記の結果から絞込み

                      where hoge.text1.Contains(keyword)

                      select hoge;

    }

     

    実際動かしてみれば、これはNGでした。。ちゃんと確認せずに書き込んでしまい申し訳ありませんでした。。。

    実際に keyword が解析されるのが、クエリを発行するときの様で、上記の様に書いていると、一番最後の

    keyword の値のみが、条件として複数回入ってしまいました。。。##全く意味無し。。 これはLinqのバグでしょうか??

    これはバグではなく,foreach が導入する変数スコープの問題です.C# 2.0 のころから,注意すべきポイントとして知られています.

    正しくは以下のように書く必要があります.

    Code Snippet

    foreach(string keyword_ in keywords)

    {

        var keyword = keyword_;

        result = from hoge in result

                 where hoge.text1.Contains(keyword)

                 select hoge;

    }

     

    以前書いたものですが,こちらをどうぞ.『C# 2.0 クイズ

     

     mrt136-2 さんからの引用
    何か、他に良い方法があるのではないかとも思うのですが、私の知識では思いつきません。。

     

    どなたか、良い方法をご存じの方はおられませんでしょうか。。

    よろしくお願いいたします。

     

    以下の記事のコメント欄で書いたものが参考になりますでしょうか?

    http://d.hatena.ne.jp/coma2n/20080717/1216269202

     

    Tesla. さんが上で紹介されている Scott Guthrie さんの記事の最後の方に書かれているのと同じアプローチです.

    2008年8月23日 15:08

すべての返信

  • 自己レスです。

     

    申し訳ありません。間違った情報を書き込んでいました。。

     

    AND検索の場合の foreach ですが、

     

    foreach(string keyword in keywords){

          result = from hoge in result <--- 上記の結果から絞込み

                      where hoge.text1.Contains(keyword)

                      select hoge;

    }

     

    実際動かしてみれば、これはNGでした。。ちゃんと確認せずに書き込んでしまい申し訳ありませんでした。。。

    実際に keyword が解析されるのが、クエリを発行するときの様で、上記の様に書いていると、一番最後の

    keyword の値のみが、条件として複数回入ってしまいました。。。##全く意味無し。。 これはLinqのバグでしょうか??

     

    じゃぁ、AND検索の場合も、OR検索の場合と同様に、1つの条件毎にクエリを発行して絞り込んでいくと

    言うことをしないといけないのでしょうか。。。

     

    何か、他に良い方法があるのではないかとも思うのですが、私の知識では思いつきません。。

     

    どなたか、良い方法をご存じの方はおられませんでしょうか。。

    よろしくお願いいたします。

     

    & 間違った情報を書き込んでしまい大変申し訳ありませんでした。。

    2008年8月22日 9:31
  • こんにちは。

     

    動的 LINQ を使用すると、抽出条件を文字列で指定できるようです。

     

    動的 LINQ (パート 1: LINQ 動的クエリライブラリの使用) - ScottGuさんのブログ翻訳
    http://www.chica2.dev-asp.net/ScottGu/result2.aspx?target=%e5%8b%95%e7%9a%84+LINQ+%ef%bc%88%e3%83%91%e3%83%bc%e3%83%88+1%3a+LINQ+%e5%8b%95%e7%9a%84%e3%82%af%e3%82%a8%e3%83%aa%e3%83%a9%e3%82%a4%e3%83%96%e3%83%a9%e3%83%aa%e3%81%ae%e4%bd%bf%e7%94%a8%ef%bc%89

    2008年8月23日 3:30
  •  mrt136-2 さんからの引用

    AND検索の場合の foreach ですが、

     

    foreach(string keyword in keywords){

          result = from hoge in result <--- 上記の結果から絞込み

                      where hoge.text1.Contains(keyword)

                      select hoge;

    }

     

    実際動かしてみれば、これはNGでした。。ちゃんと確認せずに書き込んでしまい申し訳ありませんでした。。。

    実際に keyword が解析されるのが、クエリを発行するときの様で、上記の様に書いていると、一番最後の

    keyword の値のみが、条件として複数回入ってしまいました。。。##全く意味無し。。 これはLinqのバグでしょうか??

    これはバグではなく,foreach が導入する変数スコープの問題です.C# 2.0 のころから,注意すべきポイントとして知られています.

    正しくは以下のように書く必要があります.

    Code Snippet

    foreach(string keyword_ in keywords)

    {

        var keyword = keyword_;

        result = from hoge in result

                 where hoge.text1.Contains(keyword)

                 select hoge;

    }

     

    以前書いたものですが,こちらをどうぞ.『C# 2.0 クイズ

     

     mrt136-2 さんからの引用
    何か、他に良い方法があるのではないかとも思うのですが、私の知識では思いつきません。。

     

    どなたか、良い方法をご存じの方はおられませんでしょうか。。

    よろしくお願いいたします。

     

    以下の記事のコメント欄で書いたものが参考になりますでしょうか?

    http://d.hatena.ne.jp/coma2n/20080717/1216269202

     

    Tesla. さんが上で紹介されている Scott Guthrie さんの記事の最後の方に書かれているのと同じアプローチです.

    2008年8月23日 15:08
  • Tesla様、NyaRuRu様 ご教授ありがとうございます!

     

    動的クエリライブラリについては、「おぉ!そんなものがあるのか!」的な感じでさっそく、

    ライブラリをダウンロードしてみました。

    これは使えそうです。。ただ、NyaRuRu様にご紹介いただいた リンク先でも書かれていましたが、

    「ならSQL書いとけよという気がしないでもない」 は、それもそうやね。。。と言う気もしましたが。。

     

    後、Expressionの動的組立てについては、まだ、私自身ちゃんと理解出来ていませんので、

    今から、もう一度じっくりNyaRuRu様ご紹介リンク先を熟読したいと思います。。。

    #それでも理解出来なければ、今回は動的クエリライブラリにしてしまうかも知れませんが。。

     

    それから、NyaRuRu様、foreach の件のご指摘もありがとうございました。

    C#自体についても、ちゃんと勉強している訳では無く、なんとなく使っていると言う程度なので、

    この様な間違いをしてしまうのですね。。全く面目ない限りです。。

     

    勉強になりました。本当にありがとうございました。

     

    ##まだ、Expresion については、解決(私自身が理解出来ていないだけですが)ではありませんが、

    ##充分な回答を得たと言うことで、一旦、当スレッドは締めさせて頂きたいと思います。

    ##皆様、ご回答ありがとうございました。
    2008年8月25日 0:50