C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2008/01/31 00:26
今まで LINQ to Object の基本くらいしか知らなかったので、今日は大収穫を得た。
一番の収穫はやはり LINQ to SQL。
つか、LINQ to SQL の場合、where 句のラムダ式が SQL の where 句に変換されるというのは、正直半信半疑だった。
で、帰宅して早速試してみた。

static void Main(string[] args)
{
    DataContext context = new DataContext(Settings.Default.Database1ConnectionString);
    var query =
        from target in context.GetTable<Table1>()
        where (target.Column1 == "a")
        select target;

    string queryText = query.ToString();
    Console.WriteLine(queryText);
}

[Table(Name = "Table1")]
class Table1
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int PrimaryKey;

    [Column]
    public string Column1;
}

実行結果
SELECT [t0].[PrimaryKey], [t0].[Column1]
FROM [Table1] AS [t0]
WHERE [t0].[Column1] = @p0


Σ(゚д゚lll)ガーン

ホントに where 句が where 句に・・・!
そういや、LINQ to SQL のラムダ式はデリゲートではなく System.Linq.Expressions.Expression オブジェクトに変換されると言っていたな。
逆コンパイルしてみると、確かに・・・つーか結構複雑なことやってるな。target.Column1 == "a" というラムダ式から、target とか Column1 とか == 演算子なんかのメタデータを採取して、それを元に Expression オブジェクトを構築するようなコードへと変換されている。
なるほどなるほど。

でもまぁこんなクエリー式はさすがに無理だろ。

var query =
    from target in context.GetTable<Table1>()
    where (target.Column1[1].ToString() == "a")
    where (target.Column1.IndexOf("b") <= 3)
    select target;

実行結果
SELECT [t0].[PrimaryKey], [t0].[Column1]
FROM [Table1] AS [t0]
WHERE ((
    (CASE
        WHEN (DATALENGTH(@p0) / 2) = 0 THEN CONVERT(BigInt,0)
        ELSE CONVERT(BigInt,(CONVERT(Int,CHARINDEX(@p0, [t0].[Column1]))) - 1)
     END)) <= @p1) AND ((CONVERT(NVarChar(MAX),CONVERT(NChar(1),SUBSTRING([t0].[Column1], @p2 + 1, 1)))) = @p3)




( ゚Д゚ ) ・・・。



ちなみに、自作メソッドを含ませたらさすがに無理 (実行時例外) だった。 あと IndexOf(string, int, int, StringComparison) も無理だった。でも例外メッセージがけっこう親切だった。
タグ: .NET C# ADO.NET LINQ


LINQ to SQLは楽しいですよね。

DataLoadOptionsやInheritanceMappingAttributeと戯れると、なかなか関心してしまいます。
自分でSQLを書かないと気が済まない人にはDataContext.Translateメソッドがありますし。

2008.02.01 21:02 URL | enrike #- [ 編集 ]


まだ全然いじれてないですが、セミナー聞いただけでもこれは中々面白そうだと思いました。

> DataLoadOptionsやInheritanceMappingAttribute
DataLoadOptions は遅延読み込みの挙動を制御するんでしたっけ?
InheritanceMappingAttribute は継承マッピングの制御かな?

うーん、うろ覚えw
色々戯れてみます

2008.02.02 00:54 URL | よこけん #Ay6tTHf6 [ 編集 ]












トラックバックURL↓
http://csharper.blog57.fc2.com/tb.php/200-2bbb80c5