ASP.NET Core 2.2迁移至3.0后调用存储过程遇System.InvalidCastException
解决ASP.NET Core 3.0 EF Core调用存储过程的SqlParameter类型异常
这个问题我之前帮不少开发者排查过,看似矛盾的错误提示(说不接受SqlParameter,但你明明传的就是),其实根源是SqlParameter的命名空间不匹配!
异常原因
在ASP.NET Core 3.0及以后,EF Core默认使用Microsoft.Data.SqlClient作为SQL Server的数据库提供程序,而旧版ASP.NET Core 2.2中常用的是System.Data.SqlClient。这两个命名空间下的SqlParameter虽然类名完全一样,但属于不同的程序集,EF Core的FromSqlRaw只接受前者类型的参数,所以会抛出类型转换异常。
解决步骤
统一SqlParameter的命名空间
把所有SqlParameter的引用替换为Microsoft.Data.SqlClient.SqlParameter,确保代码中没有混用两个命名空间的SqlParameter。修正后的完整代码
同时我简化了参数的初始化方式,让代码更简洁:
using Microsoft.Data.SqlClient; // 必须引用这个命名空间 // 初始化存储过程参数 var usernameParam = new SqlParameter("@USERNAME", SqlDbType.NVarChar, 50) { Value = user.Username, Direction = ParameterDirection.Input }; var passwordParam = new SqlParameter("@PASSWORD", SqlDbType.NVarChar, 50) { Value = user.Password, Direction = ParameterDirection.Input }; var msgOutParam = new SqlParameter("@MSG", SqlDbType.NVarChar, 1000) { Direction = ParameterDirection.Output }; var statusOutParam = new SqlParameter("@STATUS", SqlDbType.Int) { Direction = ParameterDirection.Output }; // 执行存储过程查询 var sql = @"EXEC PRC_USERS_LOGIN @USERNAME, @PASSWORD, @MSG OUT, @STATUS OUT"; var resultUser = ctx.Users.FromSqlRaw(sql, usernameParam, passwordParam, msgOutParam, statusOutParam) .FirstOrDefault(); // 读取输出参数的值(必须在查询执行完成后操作) var outputMsg = msgOutParam.Value?.ToString(); var outputStatus = (int?)statusOutParam.Value;
额外注意事项
- 确认你的项目中
Microsoft.EntityFrameworkCore.SqlServer包的版本和ASP.NET Core 3.0完全对应,避免版本不兼容引发的隐性问题。 - 输出参数的读取必须在
FirstOrDefault()执行之后,因为只有此时查询才真正发送到数据库并完成执行,才能获取到输出值。
内容的提问来源于stack exchange,提问作者Muhammad Aftab
相关产品推荐
相关产品推荐

