使用实体框架从存储过程中获取数据时的参数问题

Posted

技术标签:

【中文标题】使用实体框架从存储过程中获取数据时的参数问题【英文标题】:Paramater problem while using Entity Framework to get data from a stored procedure 【发布时间】:2021-10-25 16:13:14 【问题描述】:

我的目标是从我的存储过程中获取报告列表,并将此列表作为 JSON 返回。我在控制器的其他地方使用了与此类似的代码,这里的区别是我编写的存储过程需要一个参数,这就是问题所在。

抛出的错误是“System.Exception: 'Must declare the scalar variable "@DynamicCategoryId"” 我尝试了几种不同的方法来使参数工作,但没有成功。

这是我的代码:

    [HttpGet]
    [Route("GetReports/categoryId")]
    public string GetReports(int categoryId)
    
        List<GetReporsResult> paramaters = new List<GetReporsResult>();

        try
        
            SqlParameter paramCategoryId = new SqlParameter("@DynamicCategoryId", SqlDbType.Int);
            paramCategoryId.SourceColumn = "@DynamicCategoryId";
            paramCategoryId.Value = categoryId;
            paramCategoryId.Direction = ParameterDirection.Input;

            paramaters = context.GetReporsResult.FromSqlRaw("EXEC dbo.GetReports @DynamicCategoryId", paramCategoryId.Value).ToList();
        
        catch (Exception e)
        
            throw new Exception(e.Message);
        

        return JsonConvert.SerializeObject(paramaters);

    

有趣的是,如果我这样做(“EXEC dbo.GetReports” + categoryId.ToString() )它可以工作,但这不是一个好习惯。

【问题讨论】:

FromSqlRaw 的参数应该是 paramCategoryId 而不是 paramCategoryId.Value 我之前是这样的,但是我收到一条错误消息,我正在传递对象,我验证它不为空:“'SqlParameterCollection 只接受非空的SqlParameter 类型对象,不是 SqlParameter 对象。'" 这很奇怪,因为here 我们使用了SqlParameter 您是否从数据库中更新了您的实体?确保您在实体框架中拥有最新版本的存储过程。 呵呵,你使用了错误的SqlParameter类...很容易发现你的错误:SqlParameterCollection只接受非空SqlParameter类型对象,不接受SqlParameter对象。 i> 1 秒的谷歌搜索 【参考方案1】:

永远不要使用 Parameter.Value 作为参数。检查类别 id ,它可以为空。

试试这段代码,很多地方都用过很多次

var paramCategoryId = new SqlParameter("@DynamicCategoryId", categoryId);
 paramaters = context.GetReporsResult.FromSqlRaw("EXEC dbo.GetReports @DynamicCategoryId", 
paramCategoryId).ToList();

或者我经常使用

paramaters = context.GetReporsResult.FromSqlRaw("EXEC dbo.GetReports @DynamicCategoryId", 
parameters: new[]  paramCategoryId ).ToList();

【讨论】:

我试过这个并得到这个错误:“System.Exception:'SqlParameterCollection 只接受非空SqlParameter 类型对象,而不接受SqlParameter 对象。'”所以我在FromSqlRaw 中将其更改为paramCategoryId.Value,我又得到了原来的错误。 我也尝试了第二个选项,结果相同: System.Exception: 'The SqlParameterCollection only accepted non-null SqlParameter type objects, not SqlParameter objects.' 没有必要为参数创建一个数组,因为它是一个params参数 @David 我同意,这就是我给他第一个变体的原因。我太懒了,所以我使用标准数组。这样,如果我有多个参数,我就不需要更改代码。 但它是一个params 数组,因此您不会使用多个参数更改任何内容。

以上是关于使用实体框架从存储过程中获取数据时的参数问题的主要内容,如果未能解决你的问题,请参考以下文章

使用实体框架获取存储过程输出参数抛出映射错误:数据读取器与指定的不兼容

如何从实体框架中的存储过程中获取结果+数据库优先

asp.net 使用存储过程时参数为空时的处理

存储过程参数名称和实体框架

使用实体框架和存储过程进行并发检查

实体框架存储过程表值参数