Skip to content

[release/10.0] Fix invalid SQL parameter names for switch/case pattern-matched variables#37805

Open
Copilot wants to merge 4 commits intorelease/10.0from
copilot/backport-fix-efcore-37474
Open

[release/10.0] Fix invalid SQL parameter names for switch/case pattern-matched variables#37805
Copilot wants to merge 4 commits intorelease/10.0from
copilot/backport-fix-efcore-37474

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

Fixes #37465
Backports #37474

Description

When using a C# switch/case pattern-matched variable in a LINQ query (e.g., case string customerId:), EF Core 10 generates an invalid SQL parameter name starting with a digit (e.g., @5__2_Task). This is because the C# compiler generates closure field names with angle brackets (e.g., <>5__2) for pattern-matched variables, and EF Core's ExpressionTreeFuncletizer was stripping everything up to and including the last >, leaving a name that starts with a digit. The fix introduces a SanitizeCompilerGeneratedName helper that correctly extracts the user-provided variable name from within the angle brackets (e.g., extracting customerId from 5__2), and adds a safety net to prepend _ if the resulting name still starts with an invalid character.

Customer impact

Any EF Core 10 application using switch/case pattern matching to capture variables in LINQ queries will fail at runtime if the database does not accept parameter names starting with non-alphabetic characters. This is particularly critical for Azure Cosmos DB, which validates parameter names and throws a BadRequest error. SQL Server and SQLite accept these names silently but the parameter names are still incorrect/confusing. There is no simple workaround other than copying the value to a separate non-pattern-matched local variable.

How found

Customer-reported issue on GitHub. Multiple customers have been affected (confirmed by reactions on the issue).

Regression

Yes, this is a regression introduced in EF Core 10.0.1. In EF 8 and EF 9, the generated parameter names were valid (e.g., @__5__2_Task_0). The regression was introduced in EF 10 when the parameter naming logic in ExpressionTreeFuncletizer was refactored.

Testing

Added a new test Captured_variable_from_switch_case_pattern_matching to NorthwindMiscellaneousQueryTestBase that directly reproduces the reported scenario. Added SQL Server and Cosmos overrides with expected SQL/query output. The test verifies that a pattern-matched variable in a switch/case statement generates a valid parameter name (e.g., @customerId) and the query executes successfully.

Risk

Low. The fix is surgical: it only changes how compiler-generated names with angle brackets are sanitized, which only affects pattern-matched switch/case variables and certain other compiler-generated closures. A UseOldBehavior37465 AppContext switch is provided to revert to the previous behavior if needed. The change has no impact on queries that don't use pattern-matched variables.

…se pattern-matched variables

Co-authored-by: roji <1862641+roji@users.noreply.github.com>
Copilot AI changed the title [WIP] Backport fix from PR 37474 to release/10.0 Backport: Fix invalid SQL parameter names for switch/case pattern-matched variables (release/10.0) Feb 25, 2026
@roji roji changed the title Backport: Fix invalid SQL parameter names for switch/case pattern-matched variables (release/10.0) [release/10.0] Fix invalid SQL parameter names for switch/case pattern-matched variables Feb 25, 2026
@roji roji marked this pull request as ready for review February 25, 2026 10:43
@roji roji requested a review from a team as a code owner February 25, 2026 10:43
Copilot AI review requested due to automatic review settings February 25, 2026 10:43
@roji roji assigned AndriySvyryd and unassigned roji Feb 25, 2026
@roji roji requested review from AndriySvyryd and artl93 and removed request for a team February 25, 2026 10:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR backports a fix for #37465, which addresses a critical regression in EF Core 10.0.1 where switch/case pattern-matched variables generate invalid SQL parameter names starting with digits (e.g., @5__2_Task). The C# compiler generates closure field names with angle brackets for pattern-matched variables (e.g., <customerId>5__2), and EF Core's previous logic was stripping everything after the last >, leaving invalid names. The fix introduces a SanitizeCompilerGeneratedName helper that extracts the user-provided variable name from within the angle brackets and adds a safety net to prepend _ if needed.

Changes:

  • Introduce SanitizeCompilerGeneratedName helper method that correctly parses compiler-generated field names to extract user-provided variable names
  • Add AppContext switch UseOldBehavior37465 for backward compatibility
  • Add safety net to prepend underscore for parameter names starting with invalid characters
  • Add test case Captured_variable_from_switch_case_pattern_matching to verify fix

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs Core fix: adds SanitizeCompilerGeneratedName helper, quirk mode switch, and applies sanitization at field/property/method name extraction points
test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs Adds base test reproducing the switch/case pattern-matching scenario from issue #37465
test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs SQL Server override with assertion that parameter name is @customerId (not @5__2_Task)

roji and others added 2 commits February 25, 2026 12:08
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Member

@artl93 artl93 left a comment

Choose a reason for hiding this comment

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

Approved. Regression, customer reported, important scenario.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants