LambdicSql でリテラルをパラメータ化したくない場合は DirectValue か N 使おう
前回 LambdicSql ネタ書いたので、小ネタを何個か。
LambdicSql でリテラル値を使うと勝手にパラメータ化されます。
が、パラメータ化したくない時もあります。*1
using LambdicSql; using System; using System.Data.SqlClient; using static LambdicSql.SqlServer.Symbol; public class table { public int foo { get; set; } public int bar { get; set; } public string 状態 { get; set; } } public class DB { public table table { get; set; } } class Program { static void Main(string[] args) { var query = Db<DB>.Sql(db => Select(new table { foo = db.table.foo, bar = db.table.bar }). From(db.table). Where(db.table.状態 == "有効")); var qs = query.Build(typeof(SqlConnection)).Text; Console.WriteLine(qs); /* SELECT table.foo AS foo, table.bar AS bar FROM table WHERE table.状態 = @p_0 */ } }
[状態] の条件はリテラルで "有効" としているけど、@p_0 でパラメータ化されちゃう。
これを防ぐには DirectValue 使おうねー。
class Program { static void Main(string[] args) { var query = Db<DB>.Sql(db => Select(new table { foo = db.table.foo, bar = db.table.bar }). From(db.table). Where(db.table.状態 == "有効".DirectValue())); var qs = query.Build(typeof(SqlConnection)).Text; Console.WriteLine(qs); /* SELECT table.foo AS foo, table.bar AS bar FROM table WHERE table.状態 = '有効' */ } }
はい、パラメータ化されなくなった。
でも、nvarchar、nchar だと、暗黙の型変換(convert_implicit)が起きてパフォーマンスに悪影響?
そんなときは、N 使おうねー。
class Program { static void Main(string[] args) { var query = Db<DB>.Sql(db => Select(new table { foo = db.table.foo, bar = db.table.bar }). From(db.table). Where(db.table.状態 == N("有効"))); var qs = query.Build(typeof(SqlConnection)).Text; Console.WriteLine(qs); /* SELECT table.foo AS foo, table.bar AS bar FROM table WHERE table.状態 = N'有効' */ } }
暗黙の型変換のドキュメント
Data type conversion (Database Engine) - SQL Server | Microsoft Docs
パフォーマンスに影響するよーの記事
DO’s&DONT’s #2: 絶対にやらなければいけないこと – データ型を一致させる – Microsoft SQL Server Japan Support Team Blog
SQL Server のチューニングについてまとめてみる - その6 - ( CONVERT_IMPLICIT、暗黙の型変換の怖さを知ろう ) - 都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo
*1:実行プラン変わる可能性あるし