Användning av AppContext-omkopplare i SqlClient

Gäller för: .NET Framework .NET .NET Standard

Ladda ned ADO.NET

Klassen AppContext gör att SqlClient kan tillhandahålla nya funktioner samtidigt som de fortsätter att stödja anropare som är beroende av det tidigare beteendet. Användare kan välja bort en ändring av beteendet genom att ange specifika AppContext-växlar.

SqlClient läser och cachar varje switch första gången den använder den switchen. Ställ in växlar vid applikationsstart, innan du använder några SqlClient-typer. Att ändra en switch efter att SqlClient har cacchat dess värde har ingen effekt.

Aktivera MultiSubnetFailover som standard

Gäller för: .NET Framework; .NET; .NET Standard

(Tillgänglig från och med version 7.0)

För att ställa MultiSubnetFailover=true in globalt utan att ändra individuella anslutningssträngar, ställ in AppContext-switchen Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault till true vid applikationsstart:

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

Du kan också aktivera den här växeln i din App.Config:

<runtime>
  <AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault=true" />
</runtime>

När det är aktiverat fungerar alla anslutningar som om MultiSubnetFailover=true är inställd i anslutningssträngen. Den här växeln är inaktiverad som standard.

Aktivera paket multiplexering för asynkrona läsningar

Gäller för: .NET Framework; .NET; .NET Standard

(Tillgänglig från och med version 7.0)

Multipling av paket förbättrar prestanda för stora asynkrona läsåtgärder, till exempel ExecuteReaderAsync med stora resultatuppsättningar, scenarier för direktuppspelning eller massdatahämtning. Den här funktionen styrs av två aktiveringsbara AppContext-växlar. Om du anger båda växlarna till false aktiveras den nya asynkrona bearbetningssökvägen:

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

Som standard är truebåda växlarna , vilket bevarar det befintliga (kompatibla) beteendet.

Aktivera beteende för decimaltrunkering

Gäller för: .NET Framework; .NET; .NET Standard

Från och med Microsoft.Data.SqlClient 2.0 avrundas decimaldata som standard, vilket görs av SQL Server. För att aktivera det tidigare beteendet med trunkering kan du ställa in AppContext-switchen Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal till true vid applikationsstart:

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

Aktivera hanterat nätverk i Windows

Gäller för: .NET; .NET Standard

(Tillgänglig från och med version 2.0)

I Windows använder SqlClient en intern implementering av SNI-nätverksgränssnittet som standard. För att möjliggöra användning av en hanterad SNI-implementation, ställ in AppContext-switchen Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows till true vid applikationsstart:

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

Den här växeln växlar drivrutinsbeteendet för att använda en implementering av hanterade nätverk i .NET Core 2.1+ och .NET Standard 2.0+-projekt i Windows, vilket eliminerar alla beroenden för interna bibliotek för Microsoft.Data.SqlClient-biblioteket. Det är endast för testning och felsökning.

Anmärkning

Det finns några kända skillnader jämfört med den interna implementeringen. Till exempel stöder den hanterade implementationen inte icke-domänbaserad Windows-autentisering.

Inaktivera transparent nätverks-IP-upplösning

Gäller för: .NET Framework

Transparent nätverks-IP-upplösning (TNIR) är en revision av den befintliga MultiSubnetFailover-funktionen. TNIR påverkar drivrutinens anslutningssekvens om den första lösta IP-adressen för värdnamnet inte svarar och det finns flera IP-adresser som är associerade med värdnamnet. Kombinationen av TransparentNetworkIPResolution och MultiSubnetFailover väljer anslutningssekvensen:

Transparent nätverks-IP-upplösning MultiSubnetFailover Anslutningssekvens
Sann Sann TransparentNetworkIPResolution ignoreras. Drivrutinen försöker de DNS-upplösta IP-adresserna parallellt och slutför autentiseringen med den första som svarar.
Sann Falsk Drivrutinen gör flera anslutningsrundor för DNS-resolverade IP-adresser, med minst 500 millisekunder för det första försöket och successivt längre tidsgränser för varje försök, tills en anslutning lyckas eller tills den övergripande Connect Timeout har uppnåtts.
Falsk Sann Drivrutinen försöker de DNS-upplösta IP-adresserna parallellt och slutför autentiseringen med den första som svarar.
Falsk Falsk Drivrutinen försöker varje DNS-löst IP-adress i följd tills en lyckas eller Connect Timeout nås.

TransparentNetworkIPResolutionär aktiverad som standard på .NET Framework och MultiSubnetFailover är inaktiverad som standard. På .NET 5 och senare versioner är TransparentNetworkIPResolution inte ett känt nyckelord i anslutningssträngen, och att ange det (med valfritt värde) resulterar i ArgumentException (KeywordNotSupported). Dessa versioner stöder endast MultiSubnetFailover. Resten av detta avsnitt (den automatiska överskrivningen, fellägena i följande varning och AppContext-växlingen) gäller .NET Framework.

Tips/Råd

Satt MultiSubnetFailover=True på varje reťazec pripojenia, oavsett .NET-version eller om målet är Azure SQL eller lokal SQL Server. MultiSubnetFailover=True väljer en parallellkopplad kodväg som snabbt hittar den första responsiva replikan. På .NET Framework kringgår den även TNIR:s sekventiella återförsöksloop per IP-adress, vilket är en vanlig orsak till långa fördröjningar vid anslutning och timeouter under handskakningen före autentisering.

I .NET Framework, när TransparentNetworkIPResolution inte anges i anslutningssträngen, inaktiverar drivrutinen automatiskt TNIR när datakällan är en identifierad Azure SQL-slutpunkt, när nyckeln Authentication är inställd på någon Microsoft Entra ID-metod (služba Active Directory Password, služba Active Directory Integrated, služba Active Directory Interactive, služba Active Directory Service Principal, služba Active Directory Device Code Flow, služba Active Directory Managed Identity, služba Active Directory MSI, služba Active Directory Default eller služba Active Directory Workload Identity), eller när egenskapen SqlConnection.AccessToken anges. För de slutpunktssuffix som drivrutinen känner igen, se posten TransparentNetworkIPResolution i SqlConnection.ConnectionString.

Ett explicit TransparentNetworkIPResolution värde kringgår detta automatiska beteende: True aktiverar TNIR och False inaktiverar TNIR villkorslöst. För att återställa det automatiska beteendet, ta bort nyckelordet från reťazec pripojenia. Den automatiska åsidosättningen gäller inte heller när anslutningssträngen pekar på Azure SQL via ett anpassat CNAME eller ett anpassat DNS-namn vars suffix inte identifieras som en Azure SQL-slutpunkt. Den automatiska överskrivningen riktar sig specifikt mot Azure SQL; den aktiveras inte för lokal SQL Server, så TNIR är aktiverat som standard där.

Långa anslutningsfördröjningar på .NET Framework

I .NET Framework kan TransparentNetworkIPResolution=True (standardvärdet) orsaka långa anslutningsfördröjningar och timeout under handskakningen före autentisering när målets DNS-namn slås upp till flera IP-adresser och en av de första IP-adresserna inte fungerar, är inaktuell eller inte kan nås. TNIR försöker lösa IP:n i följd och ökar timeouten per försök varje runda tills totalen Connect Timeout är nådd. Du brukar observera en oväntat lång anslutningsfördröjning som slutar med detta fel:

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.

Mönstret förekommer i flera topologier:

  • Azure SQL Database, Azure SQL Managed Instance eller SQL-databas i Microsoft Fabric. Azure SQL-gatewayen routar varje autentisering till en backend-replika. När en routad anslutning misslyckas försöker TNIR om den routade backend utan att återvända till gatewayen för omdirigering, vilket förlänger fördröjningen under en backend-failover.
  • Lokal SQL Server bakom en Always On-tillgänglighetsgrupplyssnare vars DNS-namn löser sig till flera replika-IP-adresser. En föråldrad DNS-post eller en ohälsosam replika-IP testas sekventiellt innan TNIR når en fungerande replika.
  • Redundanta klusterinstanser med en klusterlyssnare för flera undernät, eller någon annan konfiguration där målets DNS-namn har flera A/AAAA poster (till exempel DNS round-robin).

För att undvika detta beteende, sätt MultiSubnetFailover=True i reťazec pripojenia:

MultiSubnetFailover=True

Denna rekommendation fungerar på alla .NET-versioner och täcker både Azure SQL och lokal SQL Server. När MultiSubnetFailover=True ignorerar drivrutinen TransparentNetworkIPResolution, försöker ansluta till de DNS-matchade IP-adresserna parallellt och slutför autentiseringen med den första replika som svarar. Trots namnet gäller MultiSubnetFailover alla lyssnarobjekt vars DNS-namn upplöses till flera mål-IP-adresser, oavsett om dessa IP-adresser finns i olika subnät, och det är säkert på fristående servrar vars DNS-namn upplöses till en enda IP-adress.

För processövergripande kontroll utan att redigera varje reťazec pripojenia, använd Enable MultiSubnetFailover som standard AppContext-switch.

Inaktivera TNIR med en AppContext-switch

För att vända standardvärdet för TransparentNetworkIPResolution från true till false i .NET Framework, ställ in AppContext-switchen Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString till true vid applikationsstart. Denna inställning ändrar bara standardvärdet när TransparentNetworkIPResolution inte finns i anslutningssträngen; den åsidosätter inte ett uttryckligen angivet värde.

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

Mer information om hur du anger dessa egenskaper finns i dokumentationen för egenskapen SqlConnection.ConnectionString.

Inaktivera den minsta tidsgränsen vid inloggning

Gäller för: .NET Framework; .NET; .NET Standard

Som standard tillämpar SqlClient en minimitid på en sekund när man beräknar den tillgängliga tiden för ett inloggningsförsök. Detta beteende förhindrar att ett inloggningsförsök väntar obegränsat när den beräknade tidsgränsen rundas ner till noll.

För att återställa det äldre beteendet, ställ in AppContext-switchen Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin till false vid applikationsstart:

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

Inaktivera blockerande beteende för ReadAsync

Gäller för: .NET Framework; .NET; .NET Standard

Från och med version 3.0 ReadAsync körs den asynkront. Tidigare versioner körs ReadAsync synkront och blockerar den anropande tråden på .NET Framework. För att kontrollera detta blockerande beteende, ställ in AppContext-switchen Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking till true eller false vid applikationsstart:

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

Aktivera rowversion-beteende för nullvärden

Gäller för: .NET Framework; .NET; .NET Standard

Från och med version 3.0, när en radversion har ett nollvärde, SqlDataReader returnerar ett DBNull värde istället för ett tomt byte[]. För att aktivera det äldre beteendet att returnera en tom byte[], aktivera AppContext-switchen Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior vid applikationsstart.

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

Ignorera osäker TLS-varning

Gäller för: .NET Framework; .NET; .NET Standard

(Tillgänglig från och med version 4.0.1)

När man använder Encrypt=false i reťazec pripojenia ger konsolen en säkerhetsvarning om TLS-versionen är 1.2 eller lägre. Undertrycka denna varning genom att aktivera följande AppContext-omkoppling vid applikationsstart:

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

Ignorera server som tillhandahålls av redundanspartner

Gäller för: .NET Framework; .NET; .NET Standard

(Tillgänglig från och med versionerna 5.1.8, 6.0.4 och 6.1.3)

Vid failover föredras failoverpartnerinformation som tillhandahålls av servern framför failoverpartnerinformation som anges i anslutningssträngen. Om du vill ignorera failover-partnerinformation som tillhandahålls av servern och endast överväga failover-partnerinformation som anges i anslutningssträngen, aktiverar du den här AppContext-omkopplaren vid programstart:

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

Tillämpa anslutningens inaktivitetstimeout

Gäller för: .NET Framework; .NET; .NET Standard

Från och med version 7.1.0 konfigurerar nyckelordet SqlConnectionStringBuilder.IdleTimeout för anslutningssträngen och egenskapen Connection Idle Timeout vilolägeskontroller och bakgrundsrensning för poolade anslutningar. Standardvärdet är 300 sekunder. Negativa värden ger upphov till en ArgumentException.

Switch- och reťazec pripojenia-inställningarna påverkar varje poolimplementation olika:

  • V1 pool. När omkopplaren är true, använder V1 sitt historiska slumpmässiga rensningsintervall på två till fyra minuter och stänger inaktiva anslutningar oavsett Connection Idle Timeout. När switchen är false och Connection Idle Timeout är icke-noll använder V1 hälften av den konfigurerade timeouten som sin rensningsfrekvens och rensar bort inaktiva anslutningar efter en eller två rensningscykler. När växeln är false och Connection Idle Timeout=0, inaktiverar V1 inaktivitetsavvisning men fortsätter med minsta poolstorleksunderhåll vid det historiskt slumpmässiga intervallet två till fyra minuter.
  • V2-pool. När switchen är true, utför V2 inte per-anslutningens inaktiva tidskontroller, men en icke-noll Connection Idle Timeout aktiverar och konfigurerar bakgrundsbeskärning. När omkopplaren är false och Connection Idle Timeout är icke-noll utför V2 kontroller av inaktivitetstid per anslutning och konfigurerar bakgrundsrensning utifrån timeout-värdet. När switchen är false och Connection Idle Timeout=0, utför V2 inte per-anslutning vilolägeskontroller eller bakgrundsbeskärning. V2 utför inte bakgrundsbeskärning när Min Pool Size är större än eller lika med Max Pool Size.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior", false);

För konfigurationsexempel, se Begränsa anslutningens inaktivitetstid.

Aktivera V2-anslutningspoolen

Gäller för: .NET Framework; .NET; .NET Standard

Från och med version 7.1 inkluderar SqlClient en alternativ anslutningspoolimplementation (V2). V1-poolen förblir standard, och switchen är som standard inställd på false.

För att aktivera V2, aktivera AppContext-switchen Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 när applikationen startar:

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

Kontrollerna för reťazec pripojenia pooling gäller för båda implementationerna. För mer information, se SQL Server connection pooling.

Använd ett anslutningstimeout för poolväntetider och nätverksanslutningar

Gäller för: .NET Framework; .NET; .NET Standard

Från och med version 7.1.0 kan tiden som spenderas på att vänta på en anslutning från poolen räknas mot anroparens Connect Timeout tidsbudget, så poolväntan och nätverksanslutningsförsöket delar på en total timeout. Aktivera Switch.Microsoft.Data.SqlClient.UseOverallConnectTimeoutForPoolWait för att använda den övergripande timeout med någon av de två implementationerna av anslutningspool:

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

Växeln är standardinställd på false. Denna standard bevarar det äldre anslutnings-timeout-beteendet, där pooloperationen får en full Connect Timeout timeout och nätverksanslutningsförsöket får ytterligare en full timeout. Som ett resultat kan Open eller OpenAsync ta längre tid än den konfigurerade Connect Timeout.

Återgå till äldre failover-alternativ vid inloggningsfel

Gäller för: .NET Framework; .NET; .NET Standard

Från och med version 7.1.0 alternerar inte SqlClient längre till failover-partnern för SQL-fel som returneras under inloggningsfasen när en anslutning med failover är konfigurerad. För att återgå till det äldre alterneringsbeteendet, aktivera AppContext-switchen Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors vid applikationsstart. Växeln är standardinställd på false.

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

Respektera en explicit nollskala på vartidsparametrar

Gäller för: .NET Framework; .NET; .NET Standard

Som standard skickar SqlClient en skala på 7 när du uttryckligen sätter skalan till 0 för datetime2, datetimeoffset eller tidsparametrar . I version 6.0 eller senare, ställ Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour in till false vid applikationsstart för att bevara den explicita skalan 0. Växeln är standardinställd på true.

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