How to pass parameters to the DbContext.Database.ExecuteSqlCommand method?

匿名 (未验证) 提交于 2019-12-03 02:00:02

问题:

Let's just suppose I have a valid need for directly executing a sql command in Entity Framework. I am having trouble figuring out how to use parameters in my sql statement. The following example (not my real example) doesn't work.

var firstName = "John"; var id = 12; var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id"; ctx.Database.ExecuteSqlCommand(sql, firstName, id); 

The ExecuteSqlCommand method doesn't allow you to pass in named parameters like in ADO.Net and the documentation for this method doesn't give any examples on how to execute a parameterized query.

How do I specify the parameters correctly?

回答1:

Try this:

var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";  ctx.Database.ExecuteSqlCommand(     sql,     new SqlParameter("@FirstName", firstname),     new SqlParameter("@Id", id)); 


回答2:

Turns out that this works.

var firstName = "John"; var id = 12; var sql = "Update [User] SET FirstName = {0} WHERE Id = {1}"; ctx.Database.ExecuteSqlCommand(sql, firstName, id); 


回答3:

You can either:

1) Pass raw arguments and use the {0} syntax. E.g:

DbContext.Database.SqlQuery("StoredProcedureName {0}", paramName); 

2) Pass DbParameter subclass arguments and use @ParamName syntax.

DbContext.Database.SqlQuery("StoredProcedureName @ParamName",                                     new SqlParameter("@ParamName", paramValue); 

If you use the first syntax, EF will actually wrap your arguments with DbParamater classes, assign them names, and replace {0} with the generated parameter name.

The first syntax if preferred because you don't need to use a factory or know what type of DbParamaters to create (SqlParameter, OracleParamter, etc.).



回答4:

Try this (edited):

ctx.Database.ExecuteSqlCommand(sql, new SqlParameter("FirstName", firstName),                                      new SqlParameter("Id", id)); 

Previous idea was wrong.



回答5:

The other answers don't work when using Oracle. You need to use : instead of @.

var sql = "Update [User] SET FirstName = :FirstName WHERE Id = :Id";  context.Database.ExecuteSqlCommand(    sql,    new OracleParameter(":FirstName", firstName),     new OracleParameter(":Id", id)); 


回答6:

public static class DbEx {     public static IEnumerable SqlQueryPrm(this System.Data.Entity.Database database, string sql, object parameters) {         using (var tmp_cmd = database.Connection.CreateCommand()) {             var dict = ToDictionary(parameters);             int i = 0;             var arr = new object[dict.Count];             foreach (var one_kvp in dict) {                 var param = tmp_cmd.CreateParameter();                 param.ParameterName = one_kvp.Key;                 if (one_kvp.Value == null) {                     param.Value = DBNull.Value;                 } else {                     param.Value = one_kvp.Value;                 }                 arr[i] = param;                 i++;             }             return database.SqlQuery(sql, arr);         }     }     private static IDictionary ToDictionary(object data) {         var attr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;         var dict = new Dictionary();         foreach (var property in data.GetType().GetProperties(attr)) {             if (property.CanRead) {                 dict.Add(property.Name, property.GetValue(data, null));             }         }         return dict;     } } 

Usage:

var names = db.Database.SqlQueryPrm("select name from position_category where id_key=@id_key", new { id_key = "mgr" }).ToList(); 


回答7:

Simplified version for Oracle. If you don't want to create OracleParameter

var sql = "Update [User] SET FirstName = :p0 WHERE Id = :p1"; context.Database.ExecuteSqlCommand(sql, firstName, id); 


回答8:

For the async Method ("ExecuteSqlCommandAsync") you can use it like this:

var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";  await ctx.Database.ExecuteSqlCommandAsync(     sql,     parameters: new[]{         new SqlParameter("@FirstName", firstname),         new SqlParameter("@Id", id)     }); 


回答9:

If your underline database data types are varchar then you should stick with teh approach below. Otherwise It would have a huge performance impact.

var firstName = new SqlParameter("@firstName", System.Data.SqlDbType.VarChar, 20)                             {                                 Value = "whatever"                             };  var id = new SqlParameter("@id", System.Data.SqlDbType.Int)                             {                                 Value = 1                             }; ctx.Database.ExecuteSqlCommand(@"Update [User] SET FirstName = @firstName WHERE Id = @id"                                , firstName, id); 

You can check Sql profiler to see the difference.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!