使用Entity Framework调用带参存储过程报错:必须声明标量变量@DynamicCategoryId
错误根因
调用FromSqlRaw方法时传递的是SqlParameter的Value属性(仅为int类型的参数值),而非完整的SqlParameter对象,EF Core无法将传入的数值和SQL语句中的@DynamicCategoryId参数名完成绑定,因此抛出变量未声明的错误。
修复后代码
[HttpGet] [Route("GetReports/{categoryId}")] public string GetReports(int categoryId) { List<GetReporsResult> reports = new List<GetReporsResult>(); try { SqlParameter paramCategoryId = new SqlParameter("@DynamicCategoryId", SqlDbType.Int); // 存储过程输入参数无需设置SourceColumn属性,可删除该行配置 paramCategoryId.Value = categoryId; paramCategoryId.Direction = ParameterDirection.Input; // 传入完整的SqlParameter对象,而非.Value属性 reports = context.GetReporsResult.FromSqlRaw("EXEC dbo.GetReports @DynamicCategoryId", paramCategoryId).ToList(); } catch (Exception e) { throw new Exception(e.Message); } return JsonConvert.SerializeObject(reports); }
额外提示:原代码中的变量名
paramaters存在拼写错误,且语义和存储的查询结果不符,已修改为reports更符合代码可读性要求。
更简化的参数化写法
你也可以选择不需要手动创建SqlParameter的写法,EF Core会自动完成参数化处理,完全规避SQL注入风险:
- 占位符写法:
reports = context.GetReporsResult.FromSqlRaw("EXEC dbo.GetReports {0}", categoryId).ToList();
- 插值写法(需使用
FromSqlInterpolated方法):
reports = context.GetReporsResult.FromSqlInterpolated($"EXEC dbo.GetReports {categoryId}").ToList();
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

