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

时间:2012-12-11 08:46:53

标签: 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();

它在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 个答案:

答案 0 :(得分:6)

这不是因为参数对象中的参数顺序 - 这是因为在您的第二个代码段中,当SP期望@Code值时,您明确地将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 PageNumber=@PageNumber,Code=@Code,PageSize=@PageSize,Member=@member", parameters).ToList();

你知道我没有按照[SP]定义的顺序将参数传递给SP,但是因为它们被命名我不需要关心。

对于传递params的不同方式,请参阅:Answer这是一些很好的例子。