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



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

644   11  

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

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

несколько параметров в хранимой процедуре, которая имеет несколько параметров в vb:

Dim result= db.Database.ExecuteSqlCommand("StoredProcedureName @a,@b,@c,@d,@e", a, b, c, d, e)

Comments

    Ничего не найдено.