Entity Framework - パラメータを渡してSQLを実行する
Entity Frameworkを使って直接SQLを実行したいときがあって、さらにパラメータの渡し方が気になったので試していました。
SqlQueryはselect文、ExecuteSqlCommandはinsert・update・delete文などを実行するのに使います。(厳密にはSqlQueryはDbRawSqlQueryを返します。)どちらのメソッドもパラメータをObject型の可変長引数として渡すことができます。
今回はSqlQueryでパラメータを渡してみたいと思います。
まずはテスト用のエンティティとDbContextを用意して、
class Item { public int Id { get; set; } public string Name { get; set; } } class AppDbContext : DbContext { private static readonly string _connectionString = new SqlConnectionStringBuilder { DataSource = ".", IntegratedSecurity = true, InitialCatalog = "Test" }.ToString(); public AppDbContext() : base(_connectionString) { } }
とりあえずパラメータを使わないでSQLを実行してみます。
using (var context = new AppDbContext()) { var item = context.Database.SqlQuery<Item>( @"select 1 as Id, N'Aaa' as Name;").First(); Console.WriteLine("{0}: {1}", item.Id, item.Name); // 1: Aaa }
引数に直接パラメータを渡す
パラメータをそのまま渡すと、SQLでは@p0
、@p1
...といった名前でパラメータを使うことができます。
using (var context = new AppDbContext()) { var item = context.Database.SqlQuery<Item>( @"select @p0 as Id, @p1 as Name;", 2, "Bbb").First(); Console.WriteLine("{0}: {1}", item.Id, item.Name); // 2: Bbb }
引数にSqlPamameterを渡す
引数にSqlParameterを使うと、任意のパラメータ名を指定できます。こっちの方が分かりやすいですが、ちょっとめんどくさいですね・・・。
using (var context = new AppDbContext()) { var item = context.Database.SqlQuery<Item>( @"select @id as Id, @name as Name;", new SqlParameter("@id", 3), new SqlParameter("@name", "Ccc")).First(); Console.WriteLine("{0}: {1}", item.Id, item.Name); // 3: Ccc }
おまけ(Dapperを使う)
Database.ConnectionプロパティでDbConnectionがとれるので、Dapperを使った方がすっきり書けますね。
using (var context = new AppDbContext()) { var item = context.Database.Connection.Query<Item>( @"select @id as Id, @name as Name;", new { id = 4, name = "Ddd" }).First(); Console.WriteLine("{0}: {1}", item.Id, item.Name); // 4: Ddd }