アーカイブ

Archive for 2007年9月7日

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();
        }
    }
}

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

 image

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メソッドを持っています。
このプログラムの実行結果は次のとおり。

 image_3

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

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

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

カテゴリー:.NET, LINQを楽しむ