Как передать параметры в метод DbContext.Database.ExecuteSqlCommand? - PullRequest
198 голосов
/ 29 марта 2011

Давайте просто предположим, что у меня есть действительная потребность в непосредственном выполнении команды 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 и документации для этого метода. не дает примеров того, как выполнить параметризованный запрос.

Как правильно указать параметры?

Ответы [ 13 ]

269 голосов
/ 20 мая 2011

Попробуйте это:

var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";

ctx.Database.ExecuteSqlCommand(
    sql,
    new SqlParameter("@FirstName", firstname),
    new SqlParameter("@Id", id));
210 голосов
/ 29 марта 2011

Оказывается, это работает.

var firstName = "John";
var id = 12;
var sql = "Update [User] SET FirstName = {0} WHERE Id = {1}";
ctx.Database.ExecuteSqlCommand(sql, firstName, id);
65 голосов
/ 25 мая 2012

Вы можете либо:

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 и т. д.).

18 голосов
/ 30 мая 2013

Другие ответы не работают при использовании Oracle.Вам нужно использовать : вместо @.

var sql = "Update [User] SET FirstName = :FirstName WHERE Id = :Id";

context.Database.ExecuteSqlCommand(
   sql,
   new OracleParameter(":FirstName", firstName), 
   new OracleParameter(":Id", id));
16 голосов
/ 29 марта 2011

Попробуйте (отредактировано):

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

Предыдущая идея была неверной.

7 голосов
/ 14 октября 2018

Для Entity Framework Core 2.0 или выше правильный способ сделать это:

var firstName = "John";
var id = 12;
ctx.Database.ExecuteSqlCommand($"Update [User] SET FirstName = {firstName} WHERE Id = {id}";

Обратите внимание, что Entity Framework предоставит вам два параметра, поэтому вы защищены от внедрения Sql.

Также обратите внимание, что это НЕ:

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

, потому что это НЕ защищает вас от впрыска Sql, и параметры не создаются.

См. this для больше.

3 голосов
/ 17 октября 2016

Упрощенная версия для Oracle. Если вы не хотите создавать OracleParameter

var sql = "Update [User] SET FirstName = :p0 WHERE Id = :p1";
context.Database.ExecuteSqlCommand(sql, firstName, id);
2 голосов
/ 06 сентября 2018
var firstName = "John";
var id = 12;

ctx.Database.ExecuteSqlCommand(@"Update [User] SET FirstName = {0} WHERE Id = {1}"
, new object[]{ firstName, id });

Это так просто !!!

Изображение для знания ссылки на параметр

enter image description here

2 голосов
/ 29 мая 2017

Для асинхронного метода («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)
    });
1 голос
/ 23 мая 2017

Если ваши базовые типы данных базы данных 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, чтобы увидеть разницу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...