Как передать параметры в DbContext.База данных.Способ ExecuteSqlCommand?
давайте просто предположим, что у меня есть действительная потребность в непосредственном выполнении команды sql в Entity Framework. У меня возникли проблемы, выясняя, как использовать параметры в моей инструкции SQL. Следующий пример (не мой реальный пример) не работает.
var firstName = "John";
var id = 12;
var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";
ctx.Database.ExecuteSqlCommand(sql, firstName, id);
метод ExecuteSqlCommand не позволяет передавать именованные параметры, как в ADO.Net а то документация для данного метода не дает никаких примеров о том, как выполнить параметризированный запрос.
Как правильно указать параметры?
11 ответов:
попробуйте это:
var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id"; ctx.Database.ExecuteSqlCommand( sql, new SqlParameter("@FirstName", firstname), new SqlParameter("@Id", id));
получается, что это работает.
var firstName = "John"; var id = 12; var sql = "Update [User] SET FirstName = {0} WHERE Id = {1}"; ctx.Database.ExecuteSqlCommand(sql, firstName, id);
Вы можете:
1) передайте необработанные Аргументы и используйте синтаксис {0}. Например:
DbContext.Database.SqlQuery("StoredProcedureName {0}", paramName);2) передайте аргументы подкласса DbParameter и используйте синтаксис @ParamName.
DbContext.Database.SqlQuery("StoredProcedureName @ParamName", new SqlParameter("@ParamName", paramValue);Если вы используете первый синтаксис, EF фактически обернет ваши аргументы классами DbParamater, назначит им имена и заменит {0} сгенерированным именем параметра.
первый синтаксис, если предпочтительно, потому что вам не нужно использовать фабрику или знать, какой тип DbParamaters чтобы создать (объект sqlparameter, OracleParamter и т. д.).
другие ответы не работают при использовании Oracle. Вы должны использовать
:вместо@.var sql = "Update [User] SET FirstName = :FirstName WHERE Id = :Id"; context.Database.ExecuteSqlCommand( sql, new OracleParameter(":FirstName", firstName), new OracleParameter(":Id", id));
попробуйте этот (отредактировано):
ctx.Database.ExecuteSqlCommand(sql, new SqlParameter("FirstName", firstName), new SqlParameter("Id", id));предыдущая идея была неверной.
упрощенная версия для Oracle. Если вы не хотите создавать OracleParameter
var sql = "Update [User] SET FirstName = :p0 WHERE Id = :p1"; context.Database.ExecuteSqlCommand(sql, firstName, id);
для асинхронного метода ("ExecuteSqlCommandAsync") вы можете использовать его следующим образом:
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) });
public static class DbEx { public static IEnumerable<T> SqlQueryPrm<T>(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<T>(sql, arr); } } private static IDictionary<string, object> ToDictionary(object data) { var attr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance; var dict = new Dictionary<string, object>(); foreach (var property in data.GetType().GetProperties(attr)) { if (property.CanRead) { dict.Add(property.Name, property.GetValue(data, null)); } } return dict; } }использование:
var names = db.Database.SqlQueryPrm<string>("select name from position_category where id_key=@id_key", new { id_key = "mgr" }).ToList();
Если ваши базовые типы данных базы данных varchar, то вы должны придерживаться подхода ниже. В противном случае запрос будет иметь огромное влияние на производительность.
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);вы можете проверить SQL profiler, чтобы увидеть разницу.
несколько параметров в хранимой процедуре, которая имеет несколько параметров в vb:
Dim result= db.Database.ExecuteSqlCommand("StoredProcedureName @a,@b,@c,@d,@e", a, b, c, d, e)

Comments