Как использовать DbContext.База данных.SqlQuery (sql, params) с хранимой процедурой? Код EF первый CTP5
у меня есть хранимая процедура, которая имеет три параметра, и я пытаюсь использовать следующее Для возврата результатов:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
сначала я попытался с помощью SqlParameter
объекты в качестве параметров, но это не сработало и бросил SqlException
появляется следующее сообщение:
процедура или функция "mySpName" ожидает параметр "@param1", который не был предоставлен.
поэтому мой вопрос заключается в том, как вы можете использовать этот метод с хранимой процедурой, которая ожидает параметры?
спасибо.
10 ответов
вы должны предоставить экземпляры SqlParameter следующим образом:
context.Database.SqlQuery<myEntityType>(
"mySpName @param1, @param2, @param3",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2),
new SqlParameter("param3", param3)
);
кроме того, вы можете использовать параметр "SQL" в качестве спецификатора формата:
context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
это решение (только) для SQL Server 2005
вы, ребята, спасатели, но, как сказал @Dan Mork, вам нужно добавить EXEC в микс. Что меня сбивало с толку, так это:--4-->
- 'EXEC' перед именем Proc
- запятые между параметрами
- отсечение ' @ ' на Параме Определения (не уверен, что бит требуется, хотя).
:
context.Database.SqlQuery<EntityType>(
"EXEC ProcName @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 });
//или
using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
}
//или
using(var context = new MyDataContext())
{
object[] parameters = { param1, param2, param3 };
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
parameters).ToList();
}
//или
using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
param1, param2, param3).ToList();
}
большинство ответов хрупкие, потому что они полагаются на порядок параметров SP. Лучше назвать сохраненные параметры Proc и дать им параметризованные значения.
чтобы использовать именованные параметры при вызове вашего SP, не беспокоясь о порядке параметров
использование именованных параметров SQL Server с ExecuteStoreQuery и ExecuteStoreCommand
описывает наилучший подход. Лучше, чем ответ Дэна Морка здесь.
- не зависит от конкатенации строк, а не полагаться на порядок параметров, определенных в СП.
например:
var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var params = new[]{
new SqlParameter("name_param", "Josh"),
new SqlParameter("age_param", 45)
};
context.Database.SqlQuery<myEntityType>(cmdText, params)
Я использую этот метод:
var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);
мне это нравится, потому что я просто бросаю GUID и Datetimes, а SqlQuery выполняет все форматирование для меня.
@Tom Halladay's ответ правильный с упоминанием о том, что вы shopuld также проверить значения null и отправить DbNullable, если params являются null, как вы получите исключение, как
параметризованный запрос '..."ожидает параметр " @parameterName", который не был предоставлен.
что-то вроде этого помог мне
public static object GetDBNullOrValue<T>(this T val)
{
bool isDbNull = true;
Type t = typeof(T);
if (Nullable.GetUnderlyingType(t) != null)
isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
else if (t.IsValueType)
isDbNull = false;
else
isDbNull = val == null;
return isDbNull ? DBNull.Value : (object) val;
}
(кредит для метода идет https://stackoverflow.com/users/284240/tim-schmelter)
тогда используйте его как:
new SqlParameter("@parameterName", parameter.GetValueOrDbNull())
или другое решение, более простое, но не общее:
new SqlParameter("@parameterName", parameter??(object)DBNull.Value)
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()
@Р0,@Р1,@Р2......
или
db.Database.SqlQuery<myEntityType>(
"exec GetNewSeqOfFoodServing @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
или
var cmdText = "exec [DoStuff] @Name = @name_param, @Age = @age_param";
var params = new[]{
new SqlParameter("name_param", "Josh"),
new SqlParameter("age_param", 45)
};
db.Database.SqlQuery<myEntityType>(cmdText, params)
или
db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
у меня было такое же сообщение об ошибке, когда я работал с вызовом хранимой процедуры, которая принимает два входных параметра и возвращает 3 значения с помощью инструкции SELECT, и я решил проблему, как показано ниже в первом подходе кода EF
SqlParameter @TableName = new SqlParameter()
{
ParameterName = "@TableName",
DbType = DbType.String,
Value = "Trans"
};
SqlParameter @FieldName = new SqlParameter()
{
ParameterName = "@FieldName",
DbType = DbType.String,
Value = "HLTransNbr"
};
object[] parameters = new object[] { @TableName, @FieldName };
List<Sample> x = this.Database.SqlQuery<Sample>("EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();
public class Sample
{
public string TableName { get; set; }
public string FieldName { get; set; }
public int NextNum { get; set; }
}
обновление: похоже, что с SQL SERVER 2005 отсутствует ключевое слово EXEC создает проблему. Поэтому, чтобы позволить ему работать со всеми версиями SQL SERVER, я обновил свой ответ и добавил EXEC в строке
List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();
entityobject_name.Database.ExecuteSqlCommand(string.Format(@"EXEC sp_name @parameter1='{0}',@path='{2}'", pvalue1, pvalue2));
здесь entityobject_name
ваш объект создан для сущности
пример: Entity ent=new entity() // ent is entityobject name here