You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至.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.SqlClient NuGet包

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.SqlClient NuGet包版本统一,避免跨版本兼容性问题
  • 避免在代码中同时引用System.Data.SqlClient和Microsoft.Data.SqlClient,彻底移除旧组件的引用
  • 手动拼接SQL语句存在SQL注入风险,推荐使用CommandType.StoredProcedure或参数化查询的方式

内容的提问来源于stack exchange,提问作者Kyle Fuller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:00:54