diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs index 61c189e738..daa0bc77e9 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs @@ -973,7 +973,7 @@ internal static class DbConnectionStringDefaults internal const bool IntegratedSecurity = false; internal const int LoadBalanceTimeout = 0; // default of 0 means don't use internal const bool MultipleActiveResultSets = false; - internal const bool MultiSubnetFailover = false; + internal static readonly bool MultiSubnetFailover = LocalAppContextSwitches.EnableMultiSubnetFailoverByDefault; internal const int MaxPoolSize = 100; internal const int MinPoolSize = 0; internal const int PacketSize = 8000; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index afb1a95a8a..12a24a2cd7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -21,6 +21,7 @@ private enum Tristate : byte internal const string UseMinimumLoginTimeoutString = @"Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin"; internal const string LegacyVarTimeZeroScaleBehaviourString = @"Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour"; private const string IgnoreServerProvidedFailoverPartnerString = @"Switch.Microsoft.Data.SqlClient.IgnoreServerProvidedFailoverPartner"; + private const string EnableMultiSubnetFailoverByDefaultString = @"Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault"; // this field is accessed through reflection in tests and should not be renamed or have the type changed without refactoring NullRow related tests private static Tristate s_legacyRowVersionNullBehavior; @@ -30,6 +31,7 @@ private enum Tristate : byte // this field is accessed through reflection in Microsoft.Data.SqlClient.Tests.SqlParameterTests and should not be renamed or have the type changed without refactoring related tests private static Tristate s_legacyVarTimeZeroScaleBehaviour; private static Tristate s_ignoreServerProvidedFailoverPartner; + private static Tristate s_multiSubnetFailoverByDefault; #if NET static LocalAppContextSwitches() @@ -236,5 +238,30 @@ public static bool IgnoreServerProvidedFailoverPartner return s_ignoreServerProvidedFailoverPartner == Tristate.True; } } + + /// + /// When set to true, the default value for MultiSubnetFailover connection string property + /// will be true instead of false. This enables parallel IP connection attempts for + /// improved connection times in multi-subnet environments. + /// This app context switch defaults to 'false'. + /// + public static bool EnableMultiSubnetFailoverByDefault + { + get + { + if (s_multiSubnetFailoverByDefault == Tristate.NotInitialized) + { + if (AppContext.TryGetSwitch(EnableMultiSubnetFailoverByDefaultString, out bool returnedValue) && returnedValue) + { + s_multiSubnetFailoverByDefault = Tristate.True; + } + else + { + s_multiSubnetFailoverByDefault = Tristate.False; + } + } + return s_multiSubnetFailoverByDefault == Tristate.True; + } + } } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index 972e56981d..0e8d8df7b5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -43,7 +43,7 @@ internal static class DEFAULT internal const bool MARS = DbConnectionStringDefaults.MultipleActiveResultSets; internal const int Max_Pool_Size = DbConnectionStringDefaults.MaxPoolSize; internal const int Min_Pool_Size = DbConnectionStringDefaults.MinPoolSize; - internal const bool MultiSubnetFailover = DbConnectionStringDefaults.MultiSubnetFailover; + internal static readonly bool MultiSubnetFailover = DbConnectionStringDefaults.MultiSubnetFailover; internal const int Packet_Size = DbConnectionStringDefaults.PacketSize; internal const string Password = DbConnectionStringDefaults.Password; internal const bool Persist_Security_Info = DbConnectionStringDefaults.PersistSecurityInfo; diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/LocalAppContextSwitchesTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/LocalAppContextSwitchesTests.cs index e6a6b9c73f..8b8dc33597 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/LocalAppContextSwitchesTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/LocalAppContextSwitchesTests.cs @@ -14,6 +14,7 @@ public class LocalAppContextSwitchesTests [InlineData("LegacyRowVersionNullBehavior", false)] [InlineData("MakeReadAsyncBlocking", false)] [InlineData("UseMinimumLoginTimeout", true)] + [InlineData("EnableMultiSubnetFailoverByDefault", false)] public void DefaultSwitchValue(string property, bool expectedDefaultValue) { var switchesType = typeof(SqlCommand).Assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");