为什么Entity Framework在更改SqlParameter命令时会抛出异常?

1Am*_*ali 12 sql-server entity-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();
Run Code Online (Sandbox Code Playgroud)

它在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)
};
Run Code Online (Sandbox Code Playgroud)

我收到这样的错误:

 Error converting data type nvarchar to int
Run Code Online (Sandbox Code Playgroud)

存储过程如下:

ALTER PROCEDURE [c].[mySpName]
    @Member INT ,
    @Code VARCHAR (50) ,
    @PageSize INT ,
    @PageNumber INT
 AS 
Run Code Online (Sandbox Code Playgroud)

为什么我得到这个订单?保持参数顺序很重要吗?我能做什么才能调用存储过程而不关心参数顺序?

============我找到一个解决方法,它完美地工作============

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();

        }
    }
Run Code Online (Sandbox Code Playgroud)

Qui*_*rdt 6

这不是因为参数对象中的参数顺序 - 这是因为在第二个代码片段中,@Code当SP Member INT期望值时,您明确地将值作为第一个参数传递.

var result  = context.Database.SqlQuery<resultClass>("mySpName @Code,  @member,@PageSize,@PageNumber" parameters).ToList();
Run Code Online (Sandbox Code Playgroud)

...你"0165210662660001"作为第一个参数传入,转换为INT失败.

参数对象中参数的顺序无关紧要,因为EF(实际上是ADO.NET)会将这些参数映射到@parametername查询字符串中的值.因此,new SqlParameter("Code","0165210662660001")将映射到@Code查询中的位置 - 第二个代码剪切的内容实际上是SP所期望的成员值的位置.

但是......您也可以使用命名参数执行SP,在这种情况下,您可以按任何顺序将参数传递给SP,如下所示:

db.Database.SqlQuery<resultClass>("mySpName PageNumber=@PageNumber,Code=@Code,PageSize=@PageSize,Member=@member", parameters).ToList();
Run Code Online (Sandbox Code Playgroud)

你看,我没有按照它们被SP定义的顺序将params传递给SP,但是因为它们被命名我不需要关心.

对于传递params的不同方式,请参阅:本答案为一些很好的例子.