从 System.Data.SqlClient 迁移到 Microsoft。Data.SqlClient

Microsoft。Data.SqlClient 是 .NET 应用中新 SQL Server 功能的支持提供者。 它保留了 System.Data.SqlClient的 ADO.NET 编程模型,但包、命名空间、默认值和某些公共类型有所不同。

把迁移当作提供者更新,而不仅仅是命名空间的替换。

计划迁移

更改代码前:

  1. 记录应用程序支持的.NET、System.Data.SqlClientSQL Server和Microsoft SQL服务版本。

  2. 清点认证模式、连接字符串关键字、自定义证书、Always Encrypted 提供程序、DbProviderFactories 配置、SQL Server 用户定义类型以及 System.Data.SqlTypes 用法。

  3. 运行应用程序当前测试,并保存连接、查询、事务、重试和性能行为的基线。

  4. 搜索直接包引用和传递包引用:

    dotnet list package --include-transitive
    

一次迁移一个应用程序或共享数据访问库。 不要在仍使用 System.Data.SqlClient 的代码和使用 Microsoft.Data.SqlClient的代码之间传递提供者专用对象。

更换包装

如果存在显式的对 System.Data.SqlClient 包的引用,请将其移除:

dotnet remove package System.Data.SqlClient

添加 Microsoft。Data.SqlClient:

dotnet add package Microsoft.Data.SqlClient

如果 Microsoft.Data.SqlClient 7.0 或更高版本使用驱动程序提供的 Microsoft Entra 认证模式,还要添加:

dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version <same-version-as-Microsoft.Data.SqlClient>

关于版本和包的选择,请参见安装、更新和部署 Microsoft。Data.SqlClient

更新命名空间

替换主要提供者命名空间:

-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;

更新引用 System.Data.SqlClient 的完全限定名、别名、生成的代码、依赖注入注册、反射字符串、配置和测试替身。

不要替换通用 System.DataSystem.Data.Common 命名空间。 Microsoft.Data.SqlClient继续使用来自这些命名空间的 ADO.NET 类型,例如 CommandTypeDbTypeDbConnectionIsolationLevelDataTableDbCommand

某些 SQL Server 特定的类型会迁移到其他Microsoft.Data命名空间:

类型 之前的命名空间 Microsoft.Data.SqlClient 命名空间
SqlDataRecordSqlMetaData Microsoft.SqlServer.Server Microsoft.Data.SqlClient.Server
SqlFileStream System.Data.SqlTypes Microsoft.Data.SqlTypes
SqlNotificationRequest System.Data.Sql Microsoft.Data.Sql
OperationAbortedException System.Data Microsoft.Data

Microsoft.Data.SqlClient5.0及以后版本中,其他SQL Server通用语言运行时(CLR)类型仍保留在 Microsoft.SqlServer.Server。 根据编译器错误和 Microsoft.Data.SqlClient API 参考逐一更新各个类型,而不是替换整个命名空间。

更新 .NET 框架配置

通过 DbProviderFactories 解析提供程序的应用程序可能需要在 Web.configApp.config 中进行提供程序注册:

<configuration>
  <system.data>
    <DbProviderFactories>
      <add name="SqlClient Data Provider"
           invariant="Microsoft.Data.SqlClient"
           description=".NET data provider for SQL Server"
           type="Microsoft.Data.SqlClient.SqlClientFactory, Microsoft.Data.SqlClient" />
    </DbProviderFactories>
  </system.data>
</configuration>

更新请求提供者不变名称的代码:

DbProviderFactory factory =
    DbProviderFactories.GetFactory("Microsoft.Data.SqlClient");

当应用程序直接创建 SqlConnection 且不使用 DbProviderFactories. 时,不要添加这个配置。

复习加密与证书验证

Microsoft。Data.SqlClient 使用比 System.Data.SqlClient 更安全的默认值。

Behavior System.Data.SqlClient Microsoft.Data.SqlClient
默认加密 Encrypt=false Encrypt=true 从4.0版本开始
服务器证书验证 只有在启用客户端加密时才验证证书 从 2.0 版本开始,当服务器强制加密时,会根据 TrustServerCertificate 验证证书,即使 Encrypt=false也是如此
严格加密 不支持 Encrypt=Strict 从 5.0 版本开始,适用于支持 TDS 8.0 的服务器
SqlConnectionStringBuilder.Encrypt 类型 bool SqlConnectionEncryptOption 从5.0版本开始

不要将 TrustServerCertificate=trueEncrypt=false 设置为通用迁移修复方案。 配置一个客户端信任的证书,并使用与证书匹配的服务器名称。 仅在无法进行验证的受控开发环境中使用 TrustServerCertificate=true

SqlConnectionEncryptOption 的更改通过隐式转换在常见赋值场景中仍与源代码兼容,但这是一个破坏二进制兼容性的变更。 重新编译每个访问 SqlConnectionStringBuilder.Encrypt 的程序集。

有关详细信息,请参阅加密和证书验证

查看连接字符串

Microsoft。Data.SqlClient 添加了 System.Data.SqlClient 无法识别的关键词和别名。 例如,它接受带有空格的Multi Subnet Failover别名,如 Application Intent 和 。

不要使用 Microsoft.Data.SqlClient.SqlConnectionStringBuilder 构建连接字符串,然后将其传递给 System.Data.SqlClient。 在分阶段迁移过程中,保持每个连接字符串生成器与其提供程序相对应。

根据 连接字符串语法审查认证、加密、重试、故障切换和证书关键词。

审查参数行为

明确测试日期和时间参数:

参数 System.Data.SqlClient 行为 Microsoft。Data.Sql客户端行为
DbType.Time具有DateTime 接受该值 使用 TimeSpan
DbType.Date具有DateTime 可以发送日期和时间组件 截断时间分量

对于 SQL Server 类型推断可能更改查询计划或转换行为的参数,请指定 SqlDbType、长度、精度和小数位数。 当数据库类型已知时,不要把它 AddWithValue 当作迁移捷径。

请查看传递性提供者的参考

直接删除软件包并不能保证 System.Data.SqlClient 已被清除。 运行:

dotnet list package --include-transitive

如果两家供应商都保留:

  1. 找出引入 System.Data.SqlClient 的包。
  2. 尽可能更新或替换该依赖。
  3. 如果两者都必须保留,应将特定于提供方的类型保留在依赖边界内。
  4. 仅将显式命名空间别名作为临时辅助。 不要将连接、事务、参数或读卡从一个提供者传递给另一个提供者。

请特别注意 SQL Server CLR 类型库以及那些在其公共 API 中公开了 System.Data.SqlClient 类型的较旧数据访问框架。

回顾全球化行为

.NET 框架和 .NET 5 之前的 .NET 版本在 Windows 上使用国家语言支持(NLS)全球化。 当前的 .NET 版本默认在 Windows、Linux 和 macOS 上使用 Unicode 国际组件(ICU)。

这种运行时间差异可能会影响一些 SqlString 比较。 SQL Server 使用NLS比较行为。 如果客户端的 SqlString 比较必须与服务器行为保持一致,请对受影响的值进行测试,并参阅 全球化和 ICU。 应用在需要时 可以使用NLS代替ICU

Microsoft.Data.SqlClient 不支持全球化不变模式。

验证迁移的应用程序

在所有支持的目标框架和操作系统上构建和测试。

验证:

  • 程序包还原和发布输出内容。
  • SQL 认证、Windows集成认证以及应用程序使用的Microsoft Entra认证。
  • TLS协商、证书验证和连接字符串解析。
  • 连接池和访问令牌的刷新。
  • 参数类型、空值、精度、尺度、日期和时间行为。
  • 交易、取消、超时、重试和故障切换。
  • 始终加密、SQL Server CLR 类型、批量复制、查询通知以及应用程序使用的其他提供者专用功能。
  • 日志记录、计数器、追踪和异常处理。

对每个支持的数据库引擎版本运行代表性查询。 成功的编译并不验证连接安全性、运行时依赖或数据转换。