PAYATHON 2026

Microsoft.Data.SqlClient 7.0.0 创建 ServerConnection 报错

排障赵师傅

结论

这是 Microsoft.Data.SqlClient 7.0.0 与当前版本的 Microsoft.SqlServer.SqlManagementObjects 存在二进制兼容问题。建议先将 Microsoft.Data.SqlClient 固定在已经验证可用的 6.1.4。等 Microsoft.SqlServer.SqlManagementObjects 发布明确兼容 7.0.0 的版本后,再同时升级这两个包。

修改连接字符串、认证方式或 ServerConnection 的 VB.NET 写法通常解决不了这个错误。程序集绑定重定向也无法补充 DLL 中不存在的类型。

原因

异常发生在这条语句中:

oCONServerConnection =
    New Microsoft.SqlServer.Management.Common.ServerConnection(sqlConnection:=oCONSQL)

此时 SqlConnection 已经成功打开,因此数据库地址、用户名、密码和 TLS 设置并非本次异常的直接原因。

创建 ServerConnection 时,SMO 会加载并检查 Microsoft.Data.SqlClient 中的相关类型。当前版本的 SMO 仍然需要:

Microsoft.Data.SqlClient.SqlAuthenticationMethod

运行时实际加载的是 Microsoft.Data.SqlClient, Version=7.0.0.0,其中缺少 SMO 所需的这个类型或兼容的类型定义,CLR 因而抛出 TypeLoadException。

这是程序集 API 或二进制契约不匹配导致的类型加载错误,与普通的数据库连接失败不同。

立即恢复运行

如果升级前使用 6.1.4 时可以正常运行,可先回退并固定到该版本。

在 Package Manager Console 中执行:

Update-Package Microsoft.Data.SqlClient -Version 6.1.4

如果项目使用 PackageReference,可在项目文件中固定版本:

<ItemGroup>
  <PackageReference Include="Microsoft.Data.SqlClient"
                    Version="6.1.4" />
</ItemGroup>

一个解决方案中可能有多个项目直接或间接引用 Microsoft.Data.SqlClient,需要逐一检查。否则,部分项目可能使用 6.1.4,另一些项目仍会把 7.0.0 复制到输出目录。

可在 Package Manager Console 中查看已安装的相关包:

Get-Package Microsoft.Data.SqlClient
Get-Package Microsoft.SqlServer.SqlManagementObjects

回退后,按以下步骤处理:

  1. 清理解决方案。
  2. 确认输出目录中没有遗留的 7.0.0 程序集。
  3. 重新还原 NuGet 包并生成解决方案。
  4. 检查最终输出目录实际加载的 Microsoft.Data.SqlClient.dll 版本。

不需要为此改写原有业务代码:

Using sqlConnection As New Microsoft.Data.SqlClient.SqlConnection(sConnectionString)
    sqlConnection.Open()

    If sqlConnection.State = ConnectionState.Open Then
        Using serverConnection As New Microsoft.SqlServer.Management.Common.ServerConnection(
            sqlConnection:=sqlConnection)

            ' 执行 SQL 脚本
        End Using
    End If
End Using

这里的 Using 用于释放资源,与修复类型加载错误无关。解决问题的办法是使用相互兼容的 NuGet 包版本。

后续如何升级

可以继续使用新版依赖,但应把 Microsoft.Data.SqlClient 和 Microsoft.SqlServer.SqlManagementObjects 作为一组依赖进行验证,避免只升级其中一个。

后续可按以下步骤操作:

  1. 查看 Microsoft.SqlServer.SqlManagementObjects 的发行说明,确认其中明确支持 Microsoft.Data.SqlClient 7.x。
  2. 确认该版本仍支持目标框架 .NET Framework 4.8。
  3. 在测试环境中同时升级两个包。
  4. 验证 SqlConnection.Open()、ServerConnection 创建、脚本批次执行和认证方式。
  5. 测试通过后再部署到生产环境。

现有信息只能确认两个包存在兼容问题,无法证明某个尚未验证的 SMO 版本已经修复。因此,即使 SMO 发布了新版本,也应先确认它是否兼容 SqlClient 7.0.0。

为什么绑定重定向通常无效

.NET Framework 项目经常通过 app.config 中的 bindingRedirect 处理程序集版本冲突,例如:

<dependentAssembly>
  <assemblyIdentity name="Microsoft.Data.SqlClient"
                    publicKeyToken="23ec7fc2d6eaa4a5"
                    culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-7.0.0.0"
                   newVersion="7.0.0.0" />
</dependentAssembly>

绑定重定向只能指定要加载的程序集版本,无法在 7.0.0 中恢复 SMO 所需的 SqlAuthenticationMethod 类型。将所有旧版本引用强制重定向到 7.0.0,可能会让这个异常稳定复现。

只有确认目标程序集保留了兼容 API 后,才能使用绑定重定向处理版本号差异。

其他注意事项

修改 uid、pwd、Authentication 或 TrustServerCertificate 无法绕过该异常。错误发生在 SMO 创建包装连接期间,与 SQL Server 是否接受登录分属不同环节。

连接字符串中的密码不宜直接写入源码或配置仓库,可以改用受保护的配置、环境变量或合适的密钥管理服务。TrustServerCertificate=True 会跳过服务器证书链验证,是否保留需要根据部署环境和证书配置单独评估。该设置与本次 TypeLoadException 无关。

在官方兼容版本发布并通过项目验证前,可以将 Microsoft.Data.SqlClient 固定在 6.1.4。依赖管理需要使用最新且相互兼容的版本组合,无须让每个包都单独保持在最高版本。

备注:内容仅供参考。