Microsoft.Data.SqlClient for SQL Server

下載 ADO.NET

Microsoft。Data.SqlClient 是支援 SQL Server、Azure SQL Database、Azure SQL 受控執行個體、Azure Synapse Analytics、Microsoft Fabric 中的 SQL 資料庫,以及 Microsoft Fabric 中的 Warehouse 的 .NET 資料提供者。 它以 NuGet 套件的形式發佈,獨立於 .NET 執行階段演進,並在新的開發中取代 System.Data.SqlClient。 它提供連線、指令、結果處理、交易、批量複製及 SQL Server 專屬功能給 .NET 應用程式。

選擇你的起點

Azure SQL 的生產環境基準

將此片段作為生產導向 Azure SQL 資料存取路徑的起點。 它會從 IConfiguration 讀取伺服器和資料庫名稱,因此這些值來自主機所設定的設定提供者,例如 appsettings.json、環境變數、Azure 應用程式組態 以及 金鑰保存庫 支援的設定。 此設定結合了這些特點:

  • 傳輸層安全(TLS)。
  • 管理式身分
  • 閒置連線復原能力。
  • 透過可配置重試邏輯(CRL)進行初始連接重試,並採用結構化日誌。
  • 指令層級重試,針對查詢中途發生的暫時錯誤。
  • 快速故障轉移群組恢復。
  • 接受取消權杖的非同步呼叫。

為了提升安全性並支援跨環境設定,請將連線資訊保留在程式碼之外。 在生產環境中,將連線資訊儲存在應用程式的設定系統中,敏感值則使用 Azure Key Vault。 如需詳細資訊,請參閱 保護連線資訊。

本文中的 C# 程式碼片段為求簡潔,省略了 using 指示詞和類別包裝程式碼。

該程式碼片段假設專案針對 .NET 8 或更新版本,並參考 Microsoft.Data.SqlClient 和 Microsoft.Data.SqlClient.Extensions.Azure 7.1.1 套件。 主機,例如 .NET Generic Host 或 ASP.NET Core,提供 ILogger 與 IConfiguration,而配置則在 Sql:Server 中提供伺服器名稱,並在 Sql:Database 中提供資料庫名稱。

public static async Task<string> QueryDatabaseNameAsync(
    IConfiguration config, ILogger logger, CancellationToken cancellationToken = default)
{
    string server = config["Sql:Server"]
        ?? throw new InvalidOperationException("Missing configuration value 'Sql:Server'.");
    string database = config["Sql:Database"]
        ?? throw new InvalidOperationException("Missing configuration value 'Sql:Database'.");

    var builder = new SqlConnectionStringBuilder
    {
        DataSource = server,
        InitialCatalog = database,
        Authentication = SqlAuthenticationMethod.ActiveDirectoryManagedIdentity,
        Encrypt = SqlConnectionEncryptOption.Strict, // TDS 8.0 encryption (server must support it)
        ConnectTimeout = 30,                         // per-attempt connect timeout in seconds
        // Retry transient failures during Open() and reconnect a dropped idle connection.
        // The configurable provider below adds another policy around Open().
        ConnectRetryCount = 3,
        ConnectRetryInterval = 10,
        MultiSubnetFailover = true,                  // recommended for TCP endpoints; enables parallel connect
        // ApplicationIntent = ApplicationIntent.ReadOnly, // uncomment to route to a readable secondary
    };

    // Add exponential backoff and jitter around Open().
    // TransientErrors is null, so the provider uses the driver's built-in transient error list.
    var openRetry = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(
        new SqlRetryLogicOption
        {
            NumberOfTries = 5,
            DeltaTime = TimeSpan.FromSeconds(3),
            MaxTimeInterval = TimeSpan.FromSeconds(60),
        });
    openRetry.Retrying += (_, args) =>
    {
        Exception last = args.Exceptions[^1];
        logger.LogWarning(
            last,
            "Retrying SQL connection to {Server}/{Database} (attempt {Attempt}) after {Delay}",
            server, database, args.RetryCount, args.Delay);
    };

    // Retry commands that hit deadlocks, lock timeouts, or common Azure SQL transient errors
    // mid-query on an established connection. Only attach this provider to commands whose
    // effect is safe to repeat.
    var commandRetry = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(
        new SqlRetryLogicOption
        {
            NumberOfTries = 4,
            DeltaTime = TimeSpan.FromSeconds(5),
            MaxTimeInterval = TimeSpan.FromSeconds(30),
            // Deadlock victim, lock-request timeout, and common Azure SQL transient errors.
            TransientErrors = new[] { 1205, 1222, 10928, 10929, 40197, 40501, 40613, 49918 },
        });
    commandRetry.Retrying += (_, args) =>
    {
        Exception last = args.Exceptions[^1];
        logger.LogWarning(
            last,
            "Retrying SQL command (attempt {Attempt}) after {Delay}",
            args.RetryCount, args.Delay);
    };

    await using var connection = new SqlConnection(builder.ConnectionString)
    {
        RetryLogicProvider = openRetry,
    };
    await connection.OpenAsync(cancellationToken);

    await using var command = new SqlCommand("SELECT DB_NAME()", connection)
    {
        RetryLogicProvider = commandRetry,
        CommandTimeout = 30,
    };

    var name = (string)await command.ExecuteScalarAsync(cancellationToken);
    logger.LogInformation("Connected to database {DatabaseName}", name);
    return name;
}

該方法會回傳它所連接的資料庫名稱並記錄 Connected to database <database>。 當重試發生時,它也會在每次重試時記錄一則警告,並附上觸發該次重試的例外。

片段的每個部分運作方式:

  • 目標:任何已設定為 Microsoft Entra 認證的 SQL 資料庫引擎 端點:Azure SQL Database、Azure SQL 受控執行個體、Microsoft Fabric 中的 SQL 資料庫,以及在 Azure 虛擬機器 上或由 Azure Arc 啟用的 SQL Server 2022 及以後版本。
  • Encrypt = SqlConnectionEncryptOption.Strict:選擇TDS 8.0加密。 它需要 SQL Server 2022 及更新版本、Azure SQL Database、Azure SQL 受控執行個體,或 Microsoft Fabric 中的 SQL 資料庫。 較舊的伺服器請使用 SqlConnectionEncryptOption.Mandatory。
  • ActiveDirectoryManagedIdentity: 僅在有受管理身份(如 Azure App 服務、Azure Functions 或 Azure 虛擬機)時運作。 本地開發時,請使用 SqlAuthenticationMethod.ActiveDirectoryDefault,其會嘗試 Azure CLI、Visual Studio 登入及其他憑證來源。 不要部署到正式環境,因為探測每個來源都會減慢連線速度。 欲了解更多資訊,請參閱 使用預設認證。
  • MultiSubnetFailover = true:嘗試對所有已解析的 IP 位址並行進行 TCP 連線,並使用第一個成功的連線,避免緩慢地依序逐一嘗試每個 IP。 設定為 Azure SQL Database、Azure SQL 受控執行個體、Microsoft Fabric 中的 SQL 資料庫、可用性群組監聽器和故障轉移叢集實例。 它在單IP目標上是安全的。 它不支援命名實例、TCP 以外的協定、超過 64 IP 位址的實例,或已被棄用的資料庫鏡像。 請改用 Always On 可用性群組。 欲了解更多資訊,請參閱 高可用性與災難復原 及 停用透明網路 IP 解析。
  • ConnectRetryCount = 3 以及 ConnectRetryInterval = 10:驅動程式在Open()期間重試符合條件的暫態故障,並在下一個指令中重新連接一個中斷的閒置連線。 預設數量為1。 三次每隔 10 秒的嘗試可撐過較長時間的重新設定或故障移轉。 驅動程式只有在伺服器名稱結尾為已知 Azure SQL 網域時才會將 1 提升到 2,.database.windows.net例如 ,因此自訂的 DNS 別名會獲得 1。
  • openRetry:指派給 SqlConnection.RetryLogicProvider 時,它會在 Open() 周圍加入指數退避機制。 當 ConnectTimeout 到期時,驅動程式會停止其內部重試,因此在 OpenAsync 擲出例外之前,最糟的情況是五次嘗試,每次最多 30 秒,再加上退避等待時間。 每次閒置重新連線嘗試也會執行完整 openRetry 政策,當該策略重試用盡時,閒置恢復就會結束。
  • Serverless 自動暫停:對於 Azure SQL Database serverless,請將ConnectTimeout提高至至少 60 秒。 第一個 Open() 程式可能在資料庫恢復時因錯誤 40613 而失敗,且 openRetry 會重試它。 客戶端逾時會以錯誤 -2出現,且不會重試,因此每次連線嘗試都必須持續超過恢復流程。 欲了解更多資訊,請參閱 自動暫停與自動繼續。
  • commandRetry:僅在可安全重播指令時,才將其附加至 SqlCommand.RetryLogicProvider:讀取、受自然鍵保護的 MERGE、透過預存程序進行 upsert 作業,以及其他冪等作業。 它會跳過交易內的重試,因此應用程式碼必須重試多語句交易。 ExecuteReader 和 ExecuteScalar 僅會重試在第一組結果開始前回傳的錯誤。 ExecuteNonQuery 重試整個呼叫。
  • 暫態錯誤清單:設定 TransientErrors 取代了內建清單。 若要擴充,請使用 SqlConfigurableRetryFactory.BaselineTransientErrors (Microsoft.Data.SqlClient 7.0 及更新版本)。
  • Retrying 事件: Retrying 在每次重試前都會觸發,包含重試次數、下一次延遲和到目前為止發生的例外。 把它路由到 ILogger 或你的遙測管線。
  • 例外:此方法不會捕捉例外。 已耗盡的提供者會擲回 AggregateException,其中包含每次嘗試的例外。 非暫態錯誤會作為原始例外傳播。 呼叫者會將它連同其餘請求脈絡一併記錄一次。
  • 取消:CancellationToken 會停止提供者在重試之間的等待。 它不會打斷駕駛人在單次ConnectRetryInterval嘗試中的Open等待。 欲了解更多資訊,請參閱 非同步程式設計。
  • 提供者壽命:程式碼片段會在每次呼叫時建立重試提供者,以保持自給自足。 在應用程式中,先建立一次後重複使用它們。

關於此配置各部分的更多資訊,請參見:

學習核心資料存取任務

連線後,請依序參閱以下文章:

  1. 執行命令以選擇結果格式並執行 Transact-SQL(T-SQL)。
  2. 設定參數 以符合資料庫約定。
  3. 使用 SqlDataReader 擷取資料 以處理資料列及多個結果。
  4. 修改儲存程序 以使用輸出參數與回傳值。
  5. 使用非同步程式設計與取消 來新增呼叫端取消和有界超時。
  6. 在新增重試或生產診斷前,先處理錯誤和訊息。

主要功能

  • 現代 .NET 支援:可運行於目前的 .NET 及 .NET Framework 版本。 關於各版本的細分,請參見 支援生命週期。
  • 預設加密:TLS Encrypt=true 加密連線為預設。 設定 Encrypt=Strict 為 TDS 8.0 加密。
  • Microsoft Entra ID 認證:無密碼連線,包含受管理身份、服務主體、互動式、整合式、預設憑證鏈及存取權杖流程。
  • Kerberos 與 NTLM:適用於內部部署 Active Directory 和舊版情境的 Windows 整合式驗證。
  • 始終加密:用戶端加密用於敏感欄位,並可選地設置安全隔區用於原地操作。
  • 大量複製:使用 SqlBulkCopy 進行高吞吐量插入。
  • 連線池:預設開啟。 一個選擇加入的 V2 集區 正在評估中。
  • 連線彈性:內建連線重試(ConnectRetryCount 和 ConnectRetryInterval)以及可自訂的重試邏輯,用於連線與指令。
  • 豐富的 SQL Server 資料型態:、datetimeoffset、sql_variantJSON、向量、空間、XML 及表格值參數。
  • 診斷:事件來源追蹤、診斷計數器、提供者統計數據,以及專門的故障排除指南。
  • 應用程式識別碼:設定SqlConnection.RegisteredApplication,以向 SQL Server 識別您的函式庫或工具(Microsoft.Data.SqlClient 7.1 及更新版本)。

開始

文章 Description
開始使用 SqlClient 驅動程式 建立專案、建立資料庫、連接、查詢,並增加連線韌性。
安裝、更新並部署 Microsoft。Data.SqlClient 安裝 NuGet 套件、選擇版本、更新驅動程式,並準備部署輸出。
支援生命週期 檢視支援的驅動版本與支援日期。
從 System.Data.SqlClient 遷移到 Microsoft。Data.SqlClient 更新套件參考、命名空間、設定,以及更改的驅動程式行為。
Microsoft。Data.SqlClient 命名空間與相容性 了解 SqlClient 如何實作 ADO.NET,以及它與 System.Data.SqlClient、.NET 和 SQL Server 的相容性。
Microsoft.Data.SqlClient 的新增功能 查詢目前的版本、重大升級變更及上游版本說明。

設定和連線

文章 Description
連接到資料來源 開啟並管理連線,並回應連線狀態變化。
連接字串 配置伺服器、資料庫、認證、加密及連線行為。
加密和憑證驗證 配置加密連線與伺服器憑證驗證。
SQL Server 連線共用 有效率地重複利用實體連接。
處理錯誤與訊息 攔截錯誤並接收資訊性訊息。

認證與安全

文章 Description
適用於 Microsoft.Data.SqlClient 的安全最佳實務 請檢視認證、授權及應用程式安全指引。
Microsoft Entra 認證 使用受控識別、服務主體、密碼及互動式流程進行連線。
保護連線資訊 請避免將憑證和連線設定納入應用程式代碼。
一律加密 保護敏感欄位值,避免被資料庫系統影響。
Always Encrypted 具有安全記憶體保護區 在加密資料上執行豐富的運算,並搭配安全的隔離區。

資料擷取與更新

文章 Description
執行指令 執行參數化的 SQL 語句與儲存程序。
DataAdapter 和 DataReader 串流結果集或填充不連通的資料結構。
使用 SqlBatch 執行多個指令 發送一組有序的指令並處理其結果。
串流資料 傳輸大型二進位、文字、XML 和 JSON 值,而不需緩衝整個值。
交易與並行 使用本地與分散式交易及並發控制。
擷取資料庫結構資訊 探索結構集合與限制。
批量複製作業 使用 SqlBulkCopy 高效載入大型資料集。
資料表值參數 將多列傳送到參數化的語句或儲存程序。
多重作用中結果集 (MARS) 在同一個連線上穿插處理多個批次。

數據類型

文章 Description
SQL Server 資料型別映射 將 SQL Server 類型對應到 .NET 類型和 System.Data.SqlTypes 類型。
JSON 資料 傳送並檢索 SQL Server json 資料型別。
向量資料 傳送並取得向量值。
XML 資料 讀取、寫入並參數化 XML 值。
二元值與大值資料 串流並更新二進位資料、FILESTREAM 及大值資料。

可靠性與診斷

文章 Description
可設定重試邏輯 使用有界重試原則來重試暫時性的連線和命令失敗。
高可用性與災難復原 連接可用性群組、監聽者及故障轉移夥伴。
SqlClient 中的事件計數器 監控活躍連線、合併連線及其他驅動指標。
啟用事件來源追蹤 詳細記錄駕駛事件以供診斷。
SqlClient 疑難排解指南 診斷常見的連線和驅動程式問題。
查詢通知 查詢結果變更時會收到通知。

SQL Server 功能

文章 Description
SQL Server 功能和 ADO.NET 瀏覽 SqlClient 提供的 SQL Server 專屬功能。
本地資料庫 連接 SQL Server Express LocalDB 實例。
資料探索與分類 從結果集讀取敏感度分類的元資料。

參考和資源

文章 Description
Microsoft.Data.SqlClient API 參考資料 瀏覽此驅動程式的 .NET API 參考資料。
AppContext 開關 設定相容性與安全性行為。
Microsoft.Data.SqlClient GitHub 存放庫 閱讀驅動程式原始碼、釋出說明和範例。
Microsoft.Data.SqlClient 範例 瀏覽 C# 的驅動程式 API 範例。
.NET 執行時 GitHub 倉庫 請閱讀 .NET 執行時函式庫的原始碼。

提出功能要求

要請求功能,請在 Microsoft.Data.SqlClient GitHub 儲存庫中開啟一個問題。