Skip to content

Add five missing SqlClient AppContext switches and a switch-latching note - #10381

Open
Fede Paganini (federico-paganini) wants to merge 5 commits into
MicrosoftDocs:livefrom
federico-paganini:sqlclient-appcontext-switches
Open

Add five missing SqlClient AppContext switches and a switch-latching note#10381
Fede Paganini (federico-paganini) wants to merge 5 commits into
MicrosoftDocs:livefrom
federico-paganini:sqlclient-appcontext-switches

Conversation

@federico-paganini

Copy link
Copy Markdown

Addresses dotnet/SqlClient#3412 — the page had drifted from the code: LocalAppContextSwitches.cs on SqlClient's current main carries five behavior switches this page doesn't mention. This PR adds one section per missing switch, in the page's existing format, with defaults and introduction versions verified against the source and release tags (6.0 / 6.1 / 7.1.0-preview2):

  • Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior (7.1.0-preview2, default true) — gates whether the Connection Idle Timeout connection-string keyword is enforced at all.
  • Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 (6.1, default false)
  • Switch.Microsoft.Data.SqlClient.UseOverallConnectTimeoutForPoolWait (7.1.0-preview2, default false)
  • Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors (7.1.0-preview2, default false)
  • Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour (6.0, default true)

It also adds a short cross-cutting note after the intro: switch values are read once and cached on first use, so a switch set after the first use of any SqlClient type is a silent no-op — none of the existing sections state this.

Two candidates were deliberately excluded: UseMinimumLoginTimeout (a property name only — its switch string is the already-documented UseOneSecFloorInTimeoutCalculationDuringLogin) and GlobalizationInvariantMode (reads the runtime's System.Globalization.Invariant, not a SqlClient switch).

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit b6094bb:

✅ Validation status: passed

File Status Preview URL Details
docs/connect/ado-net/appcontext-switches.md ✅Succeeded

For more details, please refer to the build report.

@federico-paganini

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@prmerger-automator

Copy link
Copy Markdown
Contributor

Fede Paganini (@federico-paganini) : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change.

@prmerger-automator

Copy link
Copy Markdown
Contributor

Fede Paganini (@federico-paganini) : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the SqlClient AppContext switches documentation to match current SqlClient behavior by documenting five additional switches and clarifying switch value “latching” semantics (cached on first consult).

Changes:

  • Adds a cross-cutting note explaining that switch values are cached on first consult.
  • Adds new sections documenting five previously missing SqlClient AppContext switches, including usage examples and version availability.
  • Updates ms.date.
Suppressed comments (2)

docs/connect/ado-net/appcontext-switches.md:247

  • This section doesn't state the switch's default value, even though the PR description says each added section includes defaults. Consider adding that the default is false (new behavior is on by default; switch opts back into legacy behavior).
Starting in version 7.1.0-preview2, when connecting with failover configured, SqlClient no longer alternates to the failover partner on login-phase SQL errors if the connection's parser state isn't closed. To revert to the legacy alternation behavior, enable the AppContext switch **Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors** on application startup.

docs/connect/ado-net/appcontext-switches.md:257

  • This section describes the legacy behavior but doesn't explicitly state the switch default value. Since this switch is inverted (set it to false to get the new behavior), adding the default (true) would reduce ambiguity.
By default, when a parameter's scale is explicitly set to zero for the vartime data types (`datetime2`, `datetimeoffset`, and `time`), SqlClient sends the default scale of 7 instead. Starting in version 6.0, you can disable the legacy behavior, so that an explicitly set zero scale is honored, by disabling the AppContext switch **Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour** on application startup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


The AppContext class allows SqlClient to provide new functionality while continuing to support callers who depend on the previous behavior. Users can opt out of a change in behavior by setting specific AppContext switches.

SqlClient reads each switch once and caches the value the first time the switch is consulted. Set switches at application startup, before the first use of any SqlClient type — a switch set later in the application's lifetime has no effect.

[!INCLUDE [dotnet-all](../../includes/products/applies-plain/dotnet-all.md)]

Starting in version 6.1, SqlClient includes a new connection pool implementation (V2). The V1 pool remains the default. To opt in to the V2 pool, enable the AppContext switch **Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2** on application startup.
@federico-paganini

Copy link
Copy Markdown
Author

Both findings addressed in 8a33903: the latching note now says a switch takes effect only if set before SqlClient first consults that switch (startup remains the practical guidance, since first consultation isn't generally observable), and the three sections that didn't state their switch default now do (UseConnectionPoolV2 and UseLegacyFailoverAlternationOnLoginSqlErrors default false; LegacyVarTimeZeroScaleBehaviour defaults true).

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit 8a33903:

✅ Validation status: passed

File Status Preview URL Details
docs/connect/ado-net/appcontext-switches.md ✅Succeeded

For more details, please refer to the build report.

@Court72

Copy link
Copy Markdown
Contributor

David Levy (@dlevy-msft-sql)

Can you review the proposed changes?

Important: When the changes are ready for publication, adding a #sign-off comment is the best way to signal that the PR is ready for the review team to merge.

#label:"aq-pr-triaged"
@MicrosoftDocs/public-repo-pr-review-team

@prmerger-automator prmerger-automator Bot added the aq-pr-triaged tracking label for the PR review team label Aug 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two technical corrections are required: describe idle-timeout eviction as best-effort rather than a hard maximum, and identify connection pool V2 as experimental. I also left focused wording suggestions to align the additions with the Microsoft Learn style guide and this repository's conventions. Apply the same formatting consistently throughout the new sections: use code formatting for literal switch names and “at application startup” for timing.


[!INCLUDE [dotnet-all](../../includes/products/applies-plain/dotnet-all.md)]

By default, when a parameter's scale is explicitly set to zero for the vartime data types (`datetime2`, `datetimeoffset`, and `time`), SqlClient sends the default scale of 7 instead. Starting in version 6.0, you can disable the legacy behavior, so that an explicitly set zero scale is honored, by disabling the AppContext switch **Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour** on application startup. The switch defaults to `true`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please align this paragraph with the Learn and repository style rules: format SQL Server data types in bold, format the literal switch name as code rather than bold, use “at application startup,” and remove the repeated “disable ... by disabling.” Suggested wording:

By default, SqlClient sends a scale of 7 when you explicitly set the scale to 0 for datetime2, datetimeoffset, or time parameters. With version 6.0 and later versions, set Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour to false at application startup to preserve the explicit scale of 0. The switch defaults to true.


[!INCLUDE [dotnet-all](../../includes/products/applies-plain/dotnet-all.md)]

Starting in version 6.1, SqlClient includes a new connection pool implementation (V2). The V1 pool remains the default (the switch defaults to `false`). To opt in to the V2 pool, enable the AppContext switch **Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2** on application startup.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Please state that connection pool V2 is experimental. The SqlClient 7.1 preview release notes still identify it that way, but this paragraph presents it as a normal alternative. Suggested opening: “Starting in version 6.1, SqlClient includes an alternative, experimental connection pool implementation (V2).”


[!INCLUDE [dotnet-all](../../includes/products/applies-plain/dotnet-all.md)]

Starting in version 7.1.0-preview2, when connecting with failover configured, SqlClient no longer alternates to the failover partner on login-phase SQL errors if the connection's parser state isn't closed. To revert to the legacy alternation behavior, enable the AppContext switch **Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors** on application startup. The switch defaults to `false`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please format the literal switch name as code rather than bold and use “at application startup” rather than “on application startup.” Also consider replacing the implementation-oriented phrase “if the connection's parser state isn't closed” with user-facing wording, such as “for SQL errors returned during the login phase.”


The AppContext class allows SqlClient to provide new functionality while continuing to support callers who depend on the previous behavior. Users can opt out of a change in behavior by setting specific AppContext switches.

SqlClient reads each switch once and caches the value the first time it consults that switch. Because it isn't generally observable when a given switch is first consulted, set switches at application startup, before the first use of any SqlClient type — a switch set after it has been consulted has no effect.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For shorter, more direct Learn-style wording, consider splitting this into three sentences:

SqlClient reads and caches each switch the first time it uses that switch. Set switches at application startup, before you use any SqlClient types. Changing a switch after SqlClient has cached its value has no effect.


[!INCLUDE [dotnet-all](../../includes/products/applies-plain/dotnet-all.md)]

Starting in version 7.1.0-preview2, the `Connection Idle Timeout` connection string keyword configures the maximum time, in seconds, that a pooled connection can sit unused before the pool discards it (default 300; a value of 0 disables idle expiration). The keyword is only enforced when the legacy idle-timeout behavior is disabled. With the switch at its default value of `true`, the pool preserves the historical behavior and the keyword has no effect.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This describes the configured value as a hard maximum, but the implementation defines eviction as best-effort. A connection becomes eligible for eviction after this duration and is discarded on a later retrieval or maintenance pass; the exact timing can vary by pool implementation and maintenance cadence. Please replace “configures the maximum time ... before the pool discards it” with wording such as “configures the idle duration after which a pooled connection becomes eligible for eviction.”

@federico-paganini

Copy link
Copy Markdown
Author

All applied in 9c6c69e — thanks for the precise wordings, used them as given: idle-timeout eviction now described as best-effort eligibility (which also matches what we observed empirically: eviction lands on a later maintenance pass, timing varies with the sweep cadence), pool V2 marked experimental, and the style pass throughout the new sections (switch names as code, "at application startup", bolded data type names, the three-sentence latching note, and the user-facing failover wording).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest update addresses both technical findings and the Learn style suggestions. Thanks for the quick revisions.

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit 9c6c69e:

✅ Validation status: passed

File Status Preview URL Details
docs/connect/ado-net/appcontext-switches.md ✅Succeeded

For more details, please refer to the build report.

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit e80893c:

❌ Validation status: errors

Please follow instructions here which may help to resolve issue.

File Status Preview URL Details
❌Error Details

  • [Error: CannotMergeCommit] Cannot merge commit e80893c27651cd76bcd37a2fc94aee5ba79dd97f in branch sqlclient-appcontext-switches of repository https://github.com/federico-paganini/sql-docs into branch live (commit a33efeac3d738901f8a31d8789da1a8fd4c5af9d). Please follow this documentation: https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/ to use git.exe to resolve you content conflicts locally and then push to remote.

For more details, please refer to the build report.

Note: Your PR may contain errors or warnings or suggestions unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.

@federico-paganini

Copy link
Copy Markdown
Author

Rebased onto current live and resolved the conflict in 60a6c88 — it was only the ## See also## Related content rename from #37917 colliding with the insertion point of the new sections. Adopted live's heading and bulleted link; the five added sections and the review fixes are unchanged, and the PR diff is still just this file (+53/−1).

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit 60a6c88:

✅ Validation status: passed

File Status Preview URL Details
docs/connect/ado-net/appcontext-switches.md ✅Succeeded

For more details, please refer to the build report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants