SqlClient の AppContext 切り替え

適用対象: .NET Framework .NET .NET Standard

ADO.NET のダウンロード

AppContext クラスを使用すれば、SqlClient によって、以前の動作に依存する呼び出し元を引き続きサポートしながら、新しい機能を提供することができます。 ユーザーは、特定の AppContext スイッチを設定することによって、動作の変更をオプトアウトすることができます。

MultiSubnetFailover を既定で有効にする

適用対象: .NET Framework、.NET、.NET Standard

(バージョン 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 Framework、.NET、.NET Standard

(バージョン 7.0 以降で使用可能)

パケット多重化により、大きな結果セットを使用した ExecuteReaderAsync 、ストリーミング シナリオ、一括データ取得などの大規模な非同期読み取り操作のパフォーマンスが向上します。 この機能は、2 つのオプトイン AppContext スイッチによって制御されます。 両方のスイッチを false に設定すると、新しい非同期処理パスが有効になります。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseCompatibilityAsyncBehaviour", false);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseCompatibilityProcessSni", false);

既定では、両方のスイッチが trueされ、既存の (互換性のある) 動作が保持されます。

ユーザー エージェント機能拡張機能を有効にする

適用対象: .NET Framework、.NET、.NET Standard

(バージョン 7.0 以降で使用可能)

AppContext スイッチ "Switch.Microsoft.Data.SqlClient.EnableUserAgent" が有効になっている場合、ドライバーは接続の一部としてユーザー エージェントの詳細をサーバーに送信します。 この情報は、バージョンとオペレーティング システムによるドライバーの使用状況のトラブルシューティングと定量化に役立つ情報です。 このスイッチは既定で無効になっています。 これを有効にするには、アプリケーションの起動時に AppContext スイッチを true に設定します。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableUserAgent", true);

小数点の切り捨て動作の有効化

適用対象: .NET Framework、.NET、.NET Standard

Microsoft.Data.SqlClient 2.0 以降、SQL Server と同様に、10 進データはデフォルトで四捨五入されます。 以前の切り捨て動作を有効にするには、アプリケーションの起動時に、AppContext スイッチ "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"true に設定します。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);

Windows でのマネージド ネットワークの有効化

適用対象: .NET、.NET Standard

(バージョン 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 が関連付けられている場合に、ドライバーの接続シーケンスに影響を及ぼします。 TransparentNetworkIPResolutionMultiSubnetFailoverの組み合わせは接続シーケンスを選択します:

TransparentNetworkIPResolution MultiSubnetFailover 接続シーケンス
TransparentNetworkIPResolution は無視されます。 ドライバーはDNSで解決されたIPアドレスを並列に試み、最初の応答者との認証を完成させます。
ドライバーはDNSで解決されたIPアドレスに対して複数回の接続ラウンドを実行し、初回の試みは最低500ミリ秒、そして接続成功または全体の Connect Timeout に達するまで、1回目のタイムアウトは徐々に大きくなります。
ドライバーはDNSで解決されたIPアドレスを並列に試み、最初の応答者との認証を完成させます。
ドライバーは、DNSで解決された各IPアドレスに順次試み、成功するか Connect Timeout に到達するまで続けます。

TransparentNetworkIPResolution.NET Frameworkではデフォルトで有効であり、MultiSubnetFailoverはデフォルトで無効化されています。 .NET 5以降のバージョンでは、TransparentNetworkIPResolutionは認識された接続文字列キーワードではなく、任意の値で設定するとArgumentException(KeywordNotSupported)が投げられます。 これらのバージョンは、その人だけを称え MultiSubnetFailover 。 このセクションの残りの部分(自動オーバーライド、以下の警告の故障モード、およびAppContextスイッチ)は.NETフレームワークに適用されます。

ヒント

バージョンやターゲットがAzure SQLかオンプレミスかに関わ.NETらず、すべての接続文字列でMultiSubnetFailover=Trueを設定しSQL Server。 MultiSubnetFailover=True 最初のレスポンシブレプリカを素早く見つける並列接続コードパスを選択します。 .NETフレームワークでは、TNIRの逐次的なIPごとの再試行ループも回避します。これは長い接続遅延や認証前のハンドシェイクタイムアウトの一般的な原因です。

.NET Frameworkでは、接続文字列でTransparentNetworkIPResolutionが指定されていない場合、データソースが認識されたAzure SQLエンドポイントである場合、Authenticationキーが任意のMicrosoft Entra IDメソッド(Active Directory PasswordActive 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を無効化します。 ドライバーが認識するエンドポイントの接尾辞については、SqlConnection.ConnectionStringTransparentNetworkIPResolutionエントリを参照してください。

明示的な TransparentNetworkIPResolution 値はこの自動動作を回避します。 True TNIRを有効にし、 False 無条件にTNIRを無効化します。 自動動作を復元するには、そのキーワードを接続文字列から削除してください。 また、接続文字列がカスタムCNAMEやvanity DNS名を通じてAzure SQLを指し示し、その接尾辞がAzure SQLエンドポイントとして認識されていない場合も自動オーバーライドは適用されません。 自動オーバーライドは特にAzure SQLを対象としており、オンプレミスのSQL Serverでは起動しないため、TNIRはデフォルトでオンになっています。

.NETフレームワーク上の長い接続遅延

.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 Managed Instance、またはMicrosoft FabricのSQL Database。 Azure SQLゲートウェイは各認証をバックエンドレプリカにルーティングします。 ルーティング接続が失敗すると、TNIRはゲートウェイに戻らずにルーティングされたバックエンドを再試行するため、バックエンドフェイルオーバー中の遅延が延長されます。
  • オンプレミスのSQL Serverは、Always Onの可用性グループリスナーの背後にあり、そのDNS名は複数のレプリカIPに解決されます。 古いDNSエントリや不健康なレプリカIPは、TNIRが動作するレプリカに到達する前に順次試行されます。
  • マルチサブネットクラスタリスナーを持つフェイルオーバークラスタインスタンスや、ターゲットDNS名に複数の A/AAAA レコードを持つその他の構成(DNSラウンドロビンなど)などです。

この挙動を避けるために、接続文字列にMultiSubnetFailover=Trueを設定します:

MultiSubnetFailover=True

この推奨はすべての.NETバージョンで機能し、Azure SQLとオンプレミスのSQL Serverの両方をカバーしています。 MultiSubnetFailover=True時、ドライバはTransparentNetworkIPResolutionを無視し、DNSで解決されたIPアドレスを並列に試み、最初のレスポンシブレプリカとの認証を完成させます。 名前に反して、 MultiSubnetFailover は複数のターゲットIPにDNS名で解決されるリスナーに適用されます。IPが異なるサブネットに属していなくても、DNSが単一のIPに解決されるスタンドアロンサーバーでは安全です。

すべての接続文字列を編集せずにプロセス全体で制御する場合は、デフォルトのAppContextスイッチでEnable MultiSubnetFailoverをご利用ください。

AppContextスイッチでTNIRを無効にする

.NET Framework上でTransparentNetworkIPResolutionのデフォルト値をtrueからfalseに反転させるには、アプリケーション起動時にAppContextのスイッチSwitch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionStringtrueに設定してください。 このスイッチは接続文字列にTransparentNetworkIPResolutionがない時のみデフォルト値を変更し、明示的な値を上書きしません。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString", true);

これらのプロパティの設定方法の詳細については、「SqlConnection.ConnectionString プロパティ」を参照してください。

ログイン中に最小タイムアウトを有効にする

適用対象: .NET Framework、.NET、.NET Standard

ログインの試行が無制限に待機しないようにするには、アプリケーションの起動時に AppContext スイッチ Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogintrue に設定します。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin", false);

ReadAsync のブロック動作を無効にする

適用対象: .NET Framework、.NET、.NET Standard

バージョン 3.0 以降、ReadAsync は非同期的に実行されます。 以前のバージョンでは、ReadAsync は同期的に実行され、.NET Framework 上の呼び出し元スレッドがブロックされます。 このブロック動作を制御するには、アプリケーションの起動時に AppContext スイッチ Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlockingtrue または false に設定できます。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking", false);

rowversion の null 動作の有効化

適用対象: .NET Framework、.NET、.NET Standard

バージョン 3.0 以降、rowversion の値が null の場合、SqlDataReader は空の DBNull ではなく値 byte[] を返します。 空の byte[] を返す従来の動作を有効にするには、アプリケーションの起動時に AppContext スイッチ Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior を有効にします。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior", true);

安全でない TLS 警告の抑制

適用対象: .NET Framework、.NET、.NET Standard

(バージョン 4.0.1 以降で使用できます)

接続文字列で Encrypt=false を使用する場合、TLS バージョンが 1.2 以下だとコンソールにセキュリティ警告が出力されます。 この警告は、アプリケーションの起動時に次の AppContext スイッチを有効にすることで抑制できます。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning", true);

サーバーが提供するフェールオーバーパートナーを無視する

適用対象: .NET Framework、.NET、.NET Standard

(バージョン 5.1.8、6.0.4、6.1.3 以降で使用可能)

フェールオーバー時に、サーバーから提供されるフェールオーバー パートナー情報は、接続文字列で提供されるフェールオーバー パートナー情報よりも優先されます。 サーバーによって提供されるフェールオーバー パートナー情報を無視し、接続文字列で提供されるフェールオーバー パートナー情報のみを考慮するには、アプリケーションの起動時に次の AppContext スイッチを有効にします。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.IgnoreServerProvidedFailoverPartner", true);

関連項目

AppContext クラス