Почему Entity Framework генерирует исключение при изменении порядка SqlParameter?
Im, использующий сущность Framework 4.3, сначала для вызова хранимой процедуры, как я вызываю хранимую процедуру, выглядит следующим образом:
var parameters = new[]
{
new SqlParameter("member", 1),
**new SqlParameter("Code","0165210662660001"),**
new SqlParameter("PageSize", 1),
new SqlParameter("PageNumber",1)
};
var result = context.Database.SqlQuery<resultClass>(
"mySpName @member, @Code, @PageSize,@PageNumber" parameters).ToList();
Он запускается на SqlServer, и я получаю результат.
Но если я изменю порядок параметров, например:
var result = context.Database.SqlQuery<resultClass>("mySpName @Code, @member,@PageSize,@PageNumber" parameters).ToList();
var parameters = new[]
{
**new SqlParameter("Code","0165210662660001"),**
new SqlParameter("Member", 1),
new SqlParameter("PageSize", 1),
new SqlParameter("PageNumber",1)
};
У меня возникла ошибка:
Error converting data type nvarchar to int
Хранимая процедура выглядит следующим образом:
ALTER PROCEDURE [c].[mySpName]
@Member INT ,
@Code VARCHAR (50) ,
@PageSize INT ,
@PageNumber INT
AS
Почему я получаю этот заказ?
Важно ли сохранять порядок параметров?
Что я могу сделать, чтобы я мог вызвать хранимую процедуру, не беспокоясь о порядке параметров?
============ Я нахожу обходной путь, и он отлично работает ============
public class blahContext<T>
{
int i = 0;
public IEnumerable<T> ExecuteStoreQuery(string SPname, SqlParameter[] parameters)
{
using (var context = new CADAContext())
{
string para = string.Join(", ", (from p in parameters
where !"NULL".Equals(p.Value)
select string.Concat(new object[] { "@", p.ParameterName, "={", this.i++, "}" })).ToList<string>());
object[] x = (from p in parameters
where !"NULL".Equals(p.Value)
select p.Value).ToArray<object>();
return context.Database.SqlQuery<T>(SPname + " " + para, x).ToList();
}
}
Ответы
Ответ 1
Это не из-за порядка параметров в вашем объекте параметров - потому что во втором фрагменте кода вы явно передаете значение @Code
в качестве первого параметра, когда SP ожидает значение Member INT
.
var result = context.Database.SqlQuery<resultClass>("mySpName @Code, @member,@PageSize,@PageNumber" parameters).ToList();
... вы передаете "0165210662660001"
в качестве первого параметра, а преобразование в INT не выполняется.
Порядок ваших параметров в объекте параметров не имеет значения, так как EF (на самом деле ADO.NET) сопоставляет эти параметры со значениями @parametername
в строке запроса. Таким образом, new SqlParameter("Code","0165210662660001")
будет отображаться в позиции @Code
в вашем запросе, - который во втором сокращенном коде фактически является позицией для значения члена, как ожидается SP.
Однако... вы можете выполнить SP с использованием именованных параметров, и в этом случае вы можете передать параметры SP в любом порядке, как показано ниже:
db.Database.SqlQuery<resultClass>("mySpName [email protected],[email protected],[email protected],[email protected]", parameters).ToList();
Вы видите, что я не передаю params в SP в том порядке, в котором они были определены [по SP], но поскольку они названы, мне не нужно заботиться.
Для разных способов прохождения параметров см.: Отвечать для некоторых хороших примеров.