Conversation
There was a problem hiding this comment.
Pull request overview
Refactors SqlClient’s internal connection-string/option plumbing to standardize on SqlConnectionOptions, removing the legacy DbConnectionOptions/SqlConnectionString inheritance and propagating the new type through pooling, connection creation, and related helpers.
Changes:
- Inlines former
DbConnectionOptionsparsing/state intoSqlConnectionOptionsand removesDbConnectionOptions.cs. - Updates connection/pooling code paths (factory, pool interfaces/implementations, internal connection types) to accept/use
SqlConnectionOptions. - Updates unit/functional tests and a handful of call sites to use
SqlConnectionOptions.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlConnectionStringTest.cs | Switches tests from SqlConnectionString to SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/WaitHandleDbConnectionPoolTransactionTest.cs | Updates pool test scaffolding to pass SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/TransactedConnectionPoolTest.cs | Updates mock pool signatures to match SqlConnectionOptions-based interface. |
| src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/ChannelDbConnectionPoolTest.cs | Updates channel pool tests to pass SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs | Updates JSON stack trace fixture for new signatures (partially). |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStaticMethods.cs | Switches protocol mapping helpers to SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs | Updates connect signature to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyListener.cs | Updates debug parsing/casts to SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs | Updates TypeSystem enum references to SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs | Updates network library converter mapping to SqlConnectionOptions.NETLIB (partially). |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs | Converts former SqlConnectionString : DbConnectionOptions into standalone SqlConnectionOptions and inlines parsing logic. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.Debug.cs | Moves debug-only parsing validation helpers onto SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs | Updates factory APIs and internal wiring to use SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs | Updates cached connection options fields/properties and casts to SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiContextProvider.cs | Updates auth parameter creation to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs | Updates pending request/userOptions types and pool APIs to SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/SqlConnectionPoolGroupProviderInfo.cs | Updates constructor/FailoverCheck signatures to SqlConnectionOptions (partially). |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/IDbConnectionPool.cs | Changes pool interface to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolGroup.cs | Stores/exposes SqlConnectionOptions instead of DbConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs | Updates pool API signatures to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs | Updates internal connection APIs to accept/store SqlConnectionOptions (partially). |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ServerInfo.cs | Updates server info construction to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs | Updates open/replace signatures to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs | Updates open/replace signatures to accept SqlConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionString.netfx.cs | Updates to wrap SqlConnectionOptions rather than DbConnectionOptions. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionOptions.cs | Removes obsolete base parser/option type. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs | Updates exception helper signature to accept SqlConnectionOptions. |
Comments suppressed due to low confidence (2)
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs:3912
SqlConnectionStringis still referenced later in this file (e.g.,ShouldDisableTnir(SqlConnectionString connectionOptions)), but the refactor renames/replaces it withSqlConnectionOptions. This will break NETFRAMEWORK builds; update the remaining signatures/usages toSqlConnectionOptions.
private void ResolveExtendedServerName(ServerInfo serverInfo, bool aliasLookup, SqlConnectionOptions options)
{
// @TODO: Invert to save on indentation
if (serverInfo.ExtendedServerName == null)
{
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs:25
- This PR removes
DbConnectionOptions/SqlConnectionStringby folding the parsing logic intoSqlConnectionOptions, but there are still in-repo references to the oldSqlConnectionStringtype (e.g., inSqlDependency.cs,SqlClientPermission.netfx.cs, and some netfx-only helper methods). Those need to be updated toSqlConnectionOptions(andSqlConnectionOptions.KeywordMapwhere applicable) or the build will fail.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs:16
SqlConnectionOptionsnow lives outsideSystem.Security.Permissionsfor non-.NET Framework builds, but this file unconditionally importsSystem.Security.Permissions. Since thePermissionSetAPIs are only used under#if NETFRAMEWORK, theusing System.Security.Permissions;should be guarded (or removed for non-NETFRAMEWORK) to avoid compilation failures on net8+/net9+ targets that don’t reference that assembly/package.
| @@ -53,20 +55,20 @@ internal DbConnectionString( | |||
| string restrictions, | |||
| KeyRestrictionBehavior behavior, | |||
| IReadOnlyDictionary<string, string> synonyms) | |||
There was a problem hiding this comment.
We don't need to have a constructor that accepts synonyms. The only value that is ever passed is SqlConnectionOptions.KeywordMap. I opted to leave this constructor as-is to reduce the disturbance to anyone who uses this via reflection. Modifying these CAS helper-classes isn't the focus of this PR. They support a deprecated feature and I just need them to compile
| // Need to call setter on Credential property rather than setting _credential directly as pool groups need to be checked | ||
| SqlConnectionString connectionOptions = (SqlConnectionString)ConnectionOptions; | ||
| if (UsesClearUserIdOrPassword(connectionOptions)) | ||
| if (UsesClearUserIdOrPassword(ConnectionOptions)) |
There was a problem hiding this comment.
A bunch of these casts are now redundant.
| internal SqlConnectionOptions ConnectionOptions => PoolGroup?.ConnectionOptions; | ||
|
|
||
| internal DbConnectionOptions UserConnectionOptions => _userConnectionOptions; | ||
| internal SqlConnectionOptions UserConnectionOptions => _userConnectionOptions; |
There was a problem hiding this comment.
ConnectionOptions and UserConnectionOptions look the same but are subtly different (one is the expanded form). They'll be consolidated in the next PR.
| SqlConnectionString constr = (SqlConnectionString)ConnectionOptions; | ||
|
|
||
| return constr?.WorkstationId | ||
| return ConnectionOptions?.WorkstationId |
There was a problem hiding this comment.
No comment on the nullability of ConnectionOptions. Not the focus of this PR, so I just maintained existing behavior.
| namespace Microsoft.Data.SqlClient | ||
| { | ||
| internal sealed class SqlConnectionString : DbConnectionOptions | ||
| internal sealed partial class SqlConnectionOptions |
There was a problem hiding this comment.
DbConnectionOptions was merged down into this class. It's marked partial because DbConnectionOptions had a debug partial for printing out connection string options. I've maintained that pattern here to reduce changes.
| else | ||
| { | ||
| return base.Expand(); | ||
| return _usersConnectionString; |
There was a problem hiding this comment.
DbConnectionOptions.Expand() directly returned _usersConnectionString
|
|
||
| #endregion | ||
|
|
||
| #region DbConnectionOptions methods |
There was a problem hiding this comment.
Methods carried over from DbConnectionOptions
| // which we have already demanded upon. | ||
| SqlConnectionString connStringObj = (SqlConnectionString)_con.ConnectionOptions; | ||
| #if NETFRAMEWORK | ||
| SqlConnectionOptions connStringObj = _con.ConnectionOptions; |
There was a problem hiding this comment.
The ifdef moved up because we only need the options object if we're creating a permission set.
| + @"""InnerException"":null," | ||
| + @"""HelpURL"":null," | ||
| + @"""StackTraceString"":"" at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken)\\n at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)\\n at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)\\n at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)\\n at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)\\n at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)\\n at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()\\n""," | ||
| + @"""StackTraceString"":"" at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionOptions connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionOptions userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken)\\n at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(SqlConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, SqlConnectionOptions userOptions)\\n at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, SqlConnectionOptions options, DbConnectionPoolKey poolKey, SqlConnectionOptions userOptions)\\n at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, SqlConnectionOptions userOptions, DbConnectionInternal oldConnection)\\n at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, SqlConnectionOptions userOptions, DbConnectionInternal oldConnection)\\n at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, SqlConnectionOptions userOptions, DbConnectionInternal& connection)\\n at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()\\n""," |
There was a problem hiding this comment.
The text of this exception doesn't really matter. The test covers message deserialization, so we just need valid formatting. Updated for completeness.
| ); | ||
| dbConnectionPoolGroup ??= new DbConnectionPoolGroup( | ||
| new DbConnectionOptions("DataSource=localhost;", null), | ||
| new SqlConnectionOptions("Data Source=localhost;"), |
There was a problem hiding this comment.
A side effect of this change is that it's now impossible to construct connection options from an invalid connection string, even in tests!
saurabh500
left a comment
There was a problem hiding this comment.
Looks a lot better now.
This is prep work for respecting connection timeout values in the new connection pool.
Following in the steps of #4235 , this PR removes another unnecessary inheritance relationship. This also had its roots in ADO.NET, but is now vestigial. Standardizing on SqlConnectionOptions to match the variable naming throughout the codebase. The original SqlConnectionString name implied that it was just a string, but it's really a parsed version with additional functionality.
This pull request refactors the codebase to consistently use the
SqlConnectionOptionstype in place of the olderDbConnectionOptionsandSqlConnectionStringtypes throughout the SQL client connection management code. This change improves type safety, clarity, and maintainability by standardizing connection option handling across all relevant classes and methods.Refactoring for Consistent Connection Options Handling:
Replaced all usages of
DbConnectionOptionsandSqlConnectionStringwithSqlConnectionOptionsin method parameters, constructors, and internal logic across connection-related classes such asDbConnectionInternal,DbConnectionClosed,SqlConnectionInternal, andServerInfo. [1] [2] [3] [4] [5]Updated method calls and internal logic to use
SqlConnectionOptionsmethods and properties, including static helper methods likeGetKeyValuePairandVerifyLocalHostAndFixup. [1] [2]Code Cleanup and Type Alignment:
Removed unnecessary
usingdirectives for obsolete namespaces related to connection strings, and updated type hints and field declarations to useSqlConnectionOptions. [1] [2] [3]Updated interface and method signatures in connection pool classes to accept
SqlConnectionOptionsinstead of the previous types, ensuring consistency across pooling logic. [1] [2]Internal Logic and Enum Usage:
Updated references to enums and nested types, such as
TransactionBindingEnum, to use the newSqlConnectionOptionscontext.Adjusted constructor and method implementations to align with the new type, including changes in overloads and private helper methods. [1] [2] [3] [4]
Overall, this refactoring modernizes the codebase and reduces ambiguity in how connection options are managed and passed between components.