升级至.NET Standard 2.0后使用Microsoft.Data.SqlClient遇参数错误求助
问题解决:SqlParameterCollection类型不匹配错误
错误原因
这个报错的本质是命名空间导致的类型冲突:System.Data.SqlClient.SqlParameter 和 Microsoft.Data.SqlClient.SqlParameter 是CLR认定的两个完全不同的类型,尽管类名完全一致。你升级到Microsoft.Data.SqlClient后,代码中可能存在命名空间混用,或者底层的Database对象仍依赖旧的System.Data.SqlClient组件,导致传入的参数类型不被识别。
解决方案
1. 统一命名空间引用
确保所有代码中使用的SqlParameter都来自Microsoft.Data.SqlClient:
- 替换所有文件顶部的
using System.Data.SqlClient;为using Microsoft.Data.SqlClient; - 检查项目依赖,移除对
System.Data.SqlClient的引用,确保只安装并引用Microsoft.Data.SqlClientNuGet包
2. 修正存储过程调用逻辑
你的代码中手动拼接参数列表的方式不仅容易出错,还可能加剧类型匹配问题,建议改用标准的存储过程调用方式:
方式一:使用CommandType.StoredProcedure(推荐)
using Microsoft.Data.SqlClient; using System.Data; public int GetStuff(long memberId, DateTime start, DateTime end) { var idParameter = new SqlParameter("@intID", memberId); var startMonthParameter = new SqlParameter("@intMonth1", start.Month); var endMonthParameter = new SqlParameter("@intMonth2", end.Month); var startYearParameter = new SqlParameter("@intYear", start.Year); return ExecuteStoreProcedure<int>("sp_GetStuff", idParameter, startMonthParameter, endMonthParameter, startYearParameter); } private T ExecuteStoreProcedure<T>(string procedureName, params SqlParameter[] sqlParameters) { using (var command = Database.Connection.CreateCommand()) { command.CommandText = procedureName; command.CommandType = CommandType.StoredProcedure; command.Parameters.AddRange(sqlParameters); if (command.Connection.State != ConnectionState.Open) command.Connection.Open(); using (var reader = command.ExecuteReader()) { reader.Read(); return (T)reader.GetValue(0); } } }
方式二:适配EF的SqlQuery方法
如果你需要继续使用EF的Database.SqlQuery,需确保EF版本为6.4.0及以上(该版本开始支持Microsoft.Data.SqlClient),并修改调用语法:
private T ExecuteStoreProcedure<T>(string procedureName, params SqlParameter[] sqlParameters) { // 使用EXEC语法直接调用存储过程,参数无需手动拼接 var procedure = $"EXEC {procedureName} @intID, @intMonth1, @intMonth2, @intYear"; return Database.SqlQuery<T>(procedure, sqlParameters).First(); }
3. 检查EF版本兼容性
如果你的项目依赖Entity Framework,必须升级到EF6.4.0或更高版本,旧版本EF只支持System.Data.SqlClient,无法识别Microsoft.Data.SqlClient的参数类型。
额外注意事项
- 确保所有相关项目的
Microsoft.Data.SqlClientNuGet包版本统一,避免跨版本兼容性问题 - 避免在代码中同时引用
System.Data.SqlClient和Microsoft.Data.SqlClient,彻底移除旧组件的引用 - 手动拼接SQL语句存在SQL注入风险,推荐使用
CommandType.StoredProcedure或参数化查询的方式
内容的提问来源于stack exchange,提问作者Kyle Fuller
相关产品推荐
相关产品推荐

