一番の収穫はやはり 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)
( ゚Д゚ ) ・・・。