適用於: .NET Framework
.NET
.NET 標準
AppContext 類別允許 SqlClient 提供新功能,同時繼續支援相依於之前行為的呼叫端。 使用者可以透過設定特定的 AppContext 參數,選擇退出行為中的變更。
SqlClient 會在第一次使用該交換器時讀取並快取該交換器。 在應用程式啟動時設定交換器,在使用任何 SqlClient 類型之前。 在 SqlClient 已快取其值之後變更開關,不會產生任何效果。
預設啟用 MultiSubnetFailover
適用於:.NET 框架;.NET;.NET 標準
(從 7.0 版本開始提供)
若要全域設定 MultiSubnetFailover=true 而不修改個別連接字串,請將 AppContext 切換 Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault 設定為 true 應用程式啟動時:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault", true);
你也可以在 App.Config 中啟用這個開關:
<runtime>
<AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault=true" />
</runtime>
啟用後,所有連線的行為就像 MultiSubnetFailover=true 是被設定在連接字串中。 此開關預設是關閉的。
啟用非同步讀取時的數據包多路復用
適用於:.NET 框架;.NET;.NET 標準
(從 7.0 版本開始提供)
封包多工能提升大型非同步讀取操作的效能,例如 ExecuteReaderAsync 大型結果集、串流情境或大量資料檢索。 此功能由兩個需要使用者主動選擇加入的 AppContext 開關來控制。 將兩個交換器設定為 false 啟用新的非同步處理路徑:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseCompatibilityAsyncBehaviour", false);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseCompatibilityProcessSni", false);
預設情況下,兩個開關皆為 true,這會保留現有(相容)的行為。
啟用使用者代理功能擴充
適用於:.NET 框架;.NET;.NET 標準
(從 7.0 版本開始提供)
當啟用 AppContext 交換器 Switch.Microsoft.Data.SqlClient.EnableUserAgent 時,驅動程式會將使用者代理資料傳送給伺服器,作為連線的一部分。 這些資訊有助於依版本與作業系統進行故障排除及量化驅動程式使用情況。 此開關預設是關閉的。 要啟用它,請將 AppContext 切換設定為 true 應用程式啟動時:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableUserAgent", true);
啟用十進位截斷行為
適用於:.NET 框架;.NET;.NET 標準
從 Microsoft.Data.SqlClient 2.0 開始,十進位資料預設會四捨五入,和 SQL Server 一樣。 若要啟用先前的截斷行為,你可以在應用程式啟動時,將 AppContext 切換 Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal 設為 true:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);
在 Windows 上啟用受控網路
適用於:.NET;.NET 標準
(2.0 版開始提供使用)
在 Windows 上,SqlClient 預設使用 SNI 網路介面的原生實作。 若要啟用受管理型 SNI 實作,請將 AppContext 切換 Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows 設定為 true 應用程式啟動時:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);
此參數會切換驅動程式的行為,以在 Windows 的 .NET Core 2.1+ 與 .NET Standard 2.0+ 專案中使用受控網路實作,同時消除 Microsoft.Data.SqlClient 程式庫之原生程式庫的所有相依性。 此僅用於測試與偵錯用途。
注意
與原生實作相比,有一些已知差異。 例如,受管理實作不支援非域 Windows 認證。
關閉透明網路 IP 解析
適用於:.NET Framework
透明網路 IP 解析 (TNIR) 為現有 MultiSubnetFailover 功能的修訂版本。 TNIR 影響驅動程式的連線順序,當第一個解析的主機名稱 IP 位址未回應且有多個 IP 位址與該主機名稱相關聯時。
TransparentNetworkIPResolution 與 MultiSubnetFailover 的組合會選擇連線順序:
| 透明網路IP解析 | MultiSubnetFailover | 連線順序 |
|---|---|---|
| 真 | 真 |
TransparentNetworkIPResolution 被忽略。 驅動程式嘗試平行處理 DNS 解析的 IP 位址,並與第一位回應者完成認證。 |
| 真 | 否 | 驅動程式會針對 DNS 解析出的 IP 位址進行多輪連線嘗試,第一次嘗試的最短逾時時間為 500 毫秒,且每次嘗試的逾時時間會逐步增加,直到連線成功或達到整體 Connect Timeout 為止。 |
| 否 | 真 | 驅動程式嘗試平行處理 DNS 解析的 IP 位址,並與第一位回應者完成認證。 |
| 否 | 否 | 驅動程式會依序嘗試每個經 DNS 解析得到的 IP 位址,直到其中一個成功,或達到 Connect Timeout 為止。 |
TransparentNetworkIPResolution在 .NET Framework 中預設啟用,預設MultiSubnetFailover則是停用。 在 .NET 5 及更新版本中,TransparentNetworkIPResolution沒有被識別的連接字串關鍵字,設定它(任意值)會拋ArgumentException出 (KeywordNotSupported)。 這些版本僅支援 MultiSubnetFailover。 本節其餘部分(自動覆寫、以下警告中的故障模式及 AppContext 切換)適用於 .NET 框架。
小提示
在每個 連接字串 上設定MultiSubnetFailover=True,不論 .NET 版本或目標是 Azure SQL 還是本地 SQL Server。
MultiSubnetFailover=True 選擇一條平行連接的程式碼路徑,能快速找到第一個響應式副本。 在 .NET Framework 上,它也會略過 TNIR 依 IP 逐一循序重試的迴圈;這是導致連線延遲過長和預先驗證交握逾時的常見原因。
在 .NET Framework 中,當 TransparentNetworkIPResolution 連接字串 未指定時,當資料來源被識別為Azure SQL端點、Authentication金鑰設定為任一 Microsoft Entra ID方法(Active Directory Password、 Active Directory IntegratedActive Directory InteractiveActive Directory Service PrincipalActive Directory Device Code FlowActive Directory Managed IdentityActive Directory MSIActive Directory Default、或 Active Directory Workload Identity),或設定屬性SqlConnection.AccessToken時,驅動程式會自動停用 TNIR。 關於驅動程式識別的端點後綴,請參見 TransparentNetworkIPResolutionSqlConnection.ConnectionString 中的條目。
明確指定的 TransparentNetworkIPResolution 值會略過此自動行為:True 會啟用 TNIR,而 False 會無條件停用 TNIR。 要恢復自動行為,請從 連接字串 中移除關鍵字。 當連線字串透過自訂 CNAME 或自訂網域名稱指向 Azure SQL,且其後綴未被辨識為 Azure SQL 端點時,自動覆寫也不適用。 自動覆寫專門針對 Azure SQL;它不會在內部部署的 SQL Server 上生效,因此在該環境中,TNIR 預設為啟用。
.NET Framework 上的長連線延遲
在 .NET Framework(預設)中, TransparentNetworkIPResolution=True 當目標 DNS 名稱解析為多個 IP 且其中一個早期 IP 不健康、過時或無法存取時,可能會導致長時間連線延遲及驗證前握手逾時。 TNIR 會依序嘗試已解析出的 IP 位址,並在每一輪增加每次嘗試的逾時時間,直到達到整體 Connect Timeout。 你通常會觀察到一個意外長的連線延遲,導致以下錯誤:
Connection Timeout Expired. The timeout period elapsed while attempting to consume the pre-authentication handshake acknowledgement. This could be because the pre-authentication handshake failed or the server was unable to respond back in time.
該模式在幾種拓撲中出現:
- Azure SQL Database、Azure SQL 受控執行個體,或 Microsoft Fabric 中的 SQL 資料庫。 Azure SQL 閘道會將每個認證路由到後端副本。 當路由連線失敗時,TNIR 會重試路由後端,且不會返回閘道器進行重路由,這會延長後端故障轉移的延遲。
- 本地 SQL Server 位於 Always On 可用性群組監聽器後方,該 DNS 名稱解析為多個副本 IP。 在 TNIR 連線到可正常運作的副本之前,可能會先依序嘗試過期的 DNS 記錄或狀態不正常的副本 IP。
-
具備多子網叢集監聽器的故障轉移叢集實例,或其他目標 DNS 名稱包含多個
A/AAAA紀錄的配置(例如 DNS 輪詢)。
為避免此行為,請在 連接字串 中設定MultiSubnetFailover=True:
MultiSubnetFailover=True
此建議適用於所有 .NET 版本,涵蓋 Azure SQL 及本地 SQL Server。 當 MultiSubnetFailover=True 時,驅動程式會忽略 TransparentNetworkIPResolution,並行嘗試經 DNS 解析出的 IP 位址,並與第一個有回應的複本完成驗證程序。 儘管名稱如此,MultiSubnetFailover仍適用於任何其 DNS 名稱會解析為多個目標 IP 的接聽程式,不論這些 IP 是否位於不同的子網路中;而對於 DNS 只會解析為單一 IP 的獨立伺服器而言,這樣做也是安全的。
若要在不編輯每個連線字串的情況下進行整個處理程序層級的控制,請使用 AppContext 參數 Enable MultiSubnetFailover by default。
使用 AppContext 參數停用 TNIR
若要在 .NET Framework 上將 TransparentNetworkIPResolution 的預設值從 true 改為 false,請在應用程式啟動時將 AppContext 參數 Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString 設定為 true。 此切換只會在連線字串中沒有 TransparentNetworkIPResolution 時變更預設值;不會覆寫明確指定的值。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString", true);
如需設定這些屬性的詳細資訊,請參閱 SqlConnection.ConnectionString 屬性 (英文) 文件。
在登入時設置最小逾時設定
適用於:.NET 框架;.NET;.NET 標準
為了避免登入嘗試無限期等待,你可以將 AppContext 切換 Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin 設定為 true 應用程式啟動時:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin", false);
停用 ReadAsync 的封鎖行為
適用於:.NET 框架;.NET;.NET 標準
從版本 3.0 開始,採用 ReadAsync 非同步執行。 在先前版本中,ReadAsync 會在 .NET Framework 上同步執行,並封鎖呼叫執行緒。 要控制此阻擋行為,請在應用程式啟動時將 AppContext 切換 Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking 設定為 true 或 false :
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking", false);
啟用 rowversion Null 行為
適用於:.NET 框架;.NET;.NET 標準
從版本 3.0 開始,當 rowversion 有 null 值時,會 SqlDataReader 回傳一個 DBNull 值而非空值 byte[]。 若要啟用回傳空白 byte[] 的舊版行為,請在應用程式啟動時啟用 AppContext 開關 Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior", true);
隱藏不安全的 TLS 警告
適用於:.NET 框架;.NET;.NET 標準
(4.0.1 版開始提供使用)
在連線字串中使用 Encrypt=false 時,如果 TLS 版本為 1.2 或更低,主控台會輸出安全性警告。 請在應用程式啟動時啟用以下 AppContext 開關來抑制此警告:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning", true);
忽略伺服器提供的容錯移轉合作夥伴
適用於:.NET 框架;.NET;.NET 標準
(從 5.1.8、6.0.4 和 6.1.3 版開始可用)
容錯移轉時,伺服器提供的容錯移轉夥伴資訊會優先於連接字串中提供的容錯移轉夥伴資訊。 若要忽略伺服器所提供的容錯移轉夥伴資訊,並只考慮連接字串中提供的容錯移轉夥伴資訊,請在應用程式啟動時啟用此 AppContext 參數:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.IgnoreServerProvidedFailoverPartner", true);
強制執行連線閒置超時
適用於:.NET 框架;.NET;.NET 標準
從 7.1.0-preview2 版本開始,Connection Idle Timeout連接字串 關鍵字會設定閒置時間(秒數),之後池化連線有資格被逐出(預設為 300;值為 0 則停用閒置過期)。 符合條件的連線會在後續的連線擷取或維護輪次中遭捨棄,因此確切時機會因連線池的實作與維護週期而異。 只有在停用舊版閒置逾時行為時,該關鍵字才會生效。 當此開關為其預設值 true 時,該集區會保留原有行為,而該關鍵字不會生效。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior", false);
啟用 V2 連線池
適用於:.NET 框架;.NET;.NET 標準
從 6.1 版本開始,SqlClient 包含一個替代的實驗性連線池實作(V2)。 V1 集區仍為預設值(切換開關的預設值為 false)。 要選擇加入 V2 池,請在應用程式啟動時啟用 AppContext 切換 Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2", true);
將連線池等待時間計入連線逾時
適用於:.NET 框架;.NET;.NET 標準
從 7.1.0-preview2 版本開始,等待從連線集區取得連線所花的時間,可能會計入呼叫者的 Connect Timeout 預算,因此等待集區提供連線與網路連線嘗試會共用同一個整體逾時時間。 當交換器設定為預設值 false時,池操作會獲得滿 Connect Timeout 額,網路連線嘗試則會獲得額外的滿額預算。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseOverallConnectTimeoutForPoolWait", true);
發生登入錯誤時恢復為舊版故障切換輪替
適用於:.NET 框架;.NET;.NET 標準
從 7.1.0-preview2 版開始,在已設定容錯移轉的情況下進行連線時,若登入階段傳回 SQL 錯誤,SqlClient 將不再切換到容錯移轉夥伴。 若要回復舊有交替行為,請在應用程式啟動時啟用 AppContext 切換 Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors 。 開關預設為 false。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors", true);
對 vartime 參數中明確指定的零縮放值予以保留
適用於:.NET 框架;.NET;.NET 標準
預設情況下,當你明確將 datetime2、 datetimeoffset 或 time 參數的刻度設為 0 時,SqlClient 會傳送一個 7 的刻度。 在 6.0 或更新版本中,應用程式啟動時設定 Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour 為 , false 以保留明確的 0 尺度。 開關預設為 true。
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour", false);
相關內容
- AppContext 類別 (機器翻譯)