Skip to content

Log FirstWithoutOrderByAndFilterWarning for First on a collection navigation in a subquery - #39218

Merged
AndriySvyryd merged 4 commits into
dotnet:mainfrom
SimonCropp:first-warning-collection-navigation
Oct 15, 2026
Merged

AndriySvyryd merged 4 commits into
dotnet:mainfrom
SimonCropp:first-warning-collection-navigation

Conversation

@SimonCropp

@SimonCropp SimonCropp commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #39129

FirstWithoutOrderByAndFilterWarning was not logged for First/FirstOrDefault on a collection navigation inside a projection or predicate. Navigation expansion filters the subquery by the correlation to the outer query, and TranslateFirstOrDefault treated that predicate like a user filter, even though it does not determine which of the related rows is returned.

TranslateFirstOrDefault now also logs the warning when translating an unordered subquery whose only predicate is a foreign key correlation to the outer query: an equality between the columns of a non-unique foreign key on the subquery's table and the outer columns, optionally with null checks on the outer columns. The foreign key is identified from the relational model via ColumnExpression.Column, not from the shape of the predicate.

Scope

These are deliberately not affected:

  • GroupBy(...).Select(g => g.First())
  • subqueries correlated on columns that are not a foreign key, e.g. context.Others.Where(o => o.X == b.Y).FirstOrDefault()
  • a navigation with an additional filter, including one that correlates on other columns
  • correlation on a unique foreign key, where at most one row can match. A filtered unique index counts as unique, see the review discussion.
  • subqueries over sources without table metadata (e.g. views, FromSql, and TPC hierarchies, whose columns are projected out of a UNION). These did not log the warning before either.

A hand-written subquery correlated on the foreign key columns themselves, e.g. context.Posts.Where(p => p.BlogId == b.Id).FirstOrDefault(), does log the warning, since it is the same query as the navigation.

Warning on GroupBy and non-key correlation would be equally valid, but goes beyond the issue and broke a number of existing tests (including the "What's new" GroupBy samples). Happy to extend it if that is preferred.

The Cosmos provider has its own copy of this check and is unchanged.

Tests

  • Added tests to WarningsTestBase, which runs on SQL Server and SQLite, for a navigation in a projection (warning logged), and for a navigation with a filter, with an OrderBy, or with a filter correlated on a non-key column, and a hand-written subquery correlated on a non-key column (not logged).
  • The existing FirstOrDefault_without_orderby_and_filter_issues_warning_subquery test now asserts that the warning is logged.
  • BuiltInDataTypesFixtureBase now logs the warning, since Can_read_back_mapped_enum_from_collection_first_or_default legitimately triggers it.

The SQLite and SQL Server functional tests pass locally, including the new tests.

  • I've read the guidelines for contributing and seen the walkthrough
  • I've posted a comment on an issue with a detailed description of how I am planning to contribute and got approval from a member of the team
  • The code builds and tests pass locally (also verified by our automated build checks)
  • Commit messages follow this format
  • Tests for the changes have been added (for bug fixes / features)
  • Code follows the same patterns and style as existing code in this repo

@SimonCropp
SimonCropp marked this pull request as ready for review October 11, 2026 10:48
@SimonCropp
SimonCropp requested a review from a team as a code owner October 11, 2026 10:48
Copilot AI balanced review requested due to automatic review settings October 11, 2026 10:48

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.

🟡 Changes recommended

The predicate-shape matcher also warns for qualifying hand-written correlated filters, contrary to the stated scope.

1 open finding
What changed in this PR

Adds relational warning detection for unordered First operations on collection-navigation subqueries.

Changes:

  • Detects navigation-correlation-only predicates.
  • Adds warning and suppression tests.
  • Updates fixture warning handling.
File Description
RelationalQueryableMethodTranslatingExpressionVisitor.cs Adds correlation-shape detection.
QueryLoggingSqlServerTest.cs Tests warning behavior.
BuiltInDataTypesTestBase.cs Logs the newly triggered warning.

🧠 Review effort: Balanced


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

- Match the compared columns against a non-unique foreign key instead of the predicate shape
- Add tests for subqueries correlated on non-key columns
Copilot AI balanced review requested due to automatic review settings October 12, 2026 11:18

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.

🟡 Changes recommended

TPC correlations remain undetected, filtered unique indexes can incorrectly suppress warnings, and shared-provider coverage is missing.

4 open findings

🧠 Review effort: Balanced

Comment thread test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs Outdated
- Run the warning tests for all relational providers
- Assert the warning in the existing subquery test
Copilot AI balanced review requested due to automatic review settings October 13, 2026 11:40

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.

@AndriySvyryd AndriySvyryd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

File an issue to track the cases that were out-of-scope for this PR.

- Avoid warning for correlations on computed columns projected out of a subquery
- Add a test for a subquery correlated by a computed column
Copilot AI balanced review requested due to automatic review settings October 15, 2026 08:12

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.

🔵 Needs a closer look

Subqueries with explicit HAVING filters can incorrectly trigger the warning and throw when warnings are configured as errors.

0 open findings

3 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Exclude subqueries with Having filters from warning detection

src/​EFCore.Relational/​Query/​RelationalQueryableMethodTranslatingExpressionVisitor.cs:2038

[Medium, high confidence] Exclude subqueries with a Having filter. In a customer projection, c.Orders.GroupBy(o => o.CustomerID).Where(g => g.Count() > 1).Select(g => g.Count()).FirstOrDefault() keeps the foreign-key correlation in Predicate, while SelectExpression.ApplyPredicate stores the user filter in Having (SelectExpression.cs:1771–1791). This check therefore newly logs the warning, or throws when configured, despite the explicit filter and at most one matching group. Require selectExpression.Having == null before accepting the correlation, and add a no-warning regression case to WarningsTestBase.

🧠 Review effort: Balanced

@AndriySvyryd

Copy link
Copy Markdown
Member

Thanks for your contribution!

@AndriySvyryd
AndriySvyryd merged commit 324e166 into dotnet:main Oct 15, 2026
19 checks passed
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.

FirstWithoutOrderByAndFilterWarning is not logged for First/FirstOrDefault on a collection navigation in a subquery

3 participants