LINQ to SQL:文字列検索のための2つの方法

※この投稿はMicrosoft Visual Studio 2008 Beta2で動作を確認しています。

前の投稿ではデータの抽出条件として数字の一致と大小比較を利用しています。
抽出条件で数字ではなく文字列を利用したい場合はどのようにすればよいか調べてみます。

条件として、名前の中に"タカ"という文字列がある人を抽出してみましょう。
String型が持っているメソッドを眺めていくと、Containsメソッドがあります。
これを使ってプログラムを記述してみます。

using System;
using System.Linq;

namespace LINQ4
{
    class Program
    {
        static void Main(string[] args)
        {
            LINQTESTDataContext dtc = new LINQTESTDataContext();
            dtc.Log = Console.Out;

            var query = from p in dtc.People
                        where p.Name.Contains("タカ")
                        select p;

            foreach (var item in query)
            {
                Console.WriteLine("名前={0}, 年齢={1}", item.Name, item.Age);
            }

            Console.Read();
        }
    }
}

この実行結果は次のようになります。

String.Containsの実行結果

ContainsメソッドはLIKEに変換され、またContainsメソッドに渡した引数("タカ")の前後に"%"が追加されています。
このようなSQL文が生成されることで、欲しかった結果を正しく取り出すことができています。
String型には部分一致に利用するContainsメソッド以外にStartsWith、EndsWithメソッドがありますので、
これらを使って前方一致や後方一致の検索を行うことが可能です。

これでとりあえず文字列の検索はできましたが、LINQはSQL文に似た構文を持っているのにLIKEは
持っていないのでしょうか?

調べてみたところ、次のような方法があるようです。

            var query = from p in dtc.People
                        where System.Data.Linq.SqlClient.SqlMethods.Like(p.Name, "%タカ%")
                        select p;

System.Data.Link.SqlClient名前空間にSqlMethodsというクラスが用意されており、このクラスが
Likeメソッドを持っています。
このプログラムの実行結果は次のとおり。

SqlMethos.Likeの実行結果

String.Containsを利用した場合と、生成されるSQL文もその結果も変わっていないことが確認できます。

このときちょっと注意する必要がある点として、String.Containsの場合はSQL文に渡される文字列の
前後の"%"は自動的に追加されますが、SqlMethods.Likeの場合は渡す文字列自体に"%"を
付加しておかなければいけない、という点があります。
つまり、Stringでは前方一致や後方一致検索ではStartsWithやEndsWithといったようにメソッド
そのものを使い分けますが、SqlMethods.Likeではメソッドはひとつで渡す文字列によって前方一致
だったり後方一致だったり部分一致だったりする、ということです。

生成されるSQL文は同じですから、通常はString.Contains等を使っていればいいように思います。
Likeを使わないといけない例を見つけたのですが、それは別の記事で。

公開 07-09-2007 05:46 投稿者 ono
カテゴリ:

コメント

 

かるあ said:

このあたり VB.NET とちょっと違うんですね。
VB だと Like があって
where p.Name Like "*タカ*"
って感じで書く感じですね。([%] でなく [*])

Containts の場合必ず前後に % が付加されるので Like で書く場合よりパフォーマンス的には不利になるのかな。
9月 8, 2007 22:10
 

ono said:

Containsは"%hoge%"になりますが、StartsWithなら"hoge%"、EndsWithなら"%hoge"になります。
適切なものを使えば同じSQL文が生成されるので、パフォーマンスは変わりませんね。
9月 9, 2007 0:28
 

かるあ said:

なるほどー、そう変換されるんですね。
ありがとうございます。

適切なものを探すのは大変そうですね。
ログに出しながら確認したりしながらちょっとずつ調べてます。
9月 9, 2007 0:39
この投稿に対する新規コメントはできません
SkinName:iroha_Blog2
Powered by Community Server, by Telligent Systems