Skip to content

Fix UseProjection over-projecting when the entity is a record#9889

Merged
glen-84 merged 2 commits into
mainfrom
gai/record-projection-over-projection
Jun 10, 2026
Merged

Fix UseProjection over-projecting when the entity is a record#9889
glen-84 merged 2 commits into
mainfrom
gai/record-projection-over-projection

Conversation

@glen-84

@glen-84 glen-84 commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

  • UseProjection projected every mapped column when the entity type was a non-positional C# record, ignoring the GraphQL selection set.
  • The instance-reuse heuristic added for EF constructor service injection treated the compiler-generated record copy constructor (protected R(R original)) as an injection constructor, turning the selector into an identity expression.
  • ShouldReuseExistingInstance in QueryableProjectionScopeExtensions now excludes record copy constructors, mirroring the equivalent fix already made for QueryContext selectors in Fix QueryContext selector for record projections #9459.

Test plan

  • New regression test asserts the generated SQL selects only the requested column for a record entity (failed with SELECT "p"."Id", "p"."Description", "p"."Name" before the fix, now SELECT "p"."Id").
  • Data.EntityFramework.Tests, Data.Projections.Tests, and Data.Tests all pass, including the EF constructor-injection tests the heuristic was introduced for.

Closes #9886

Copilot AI review requested due to automatic review settings June 10, 2026 14:05

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

Fixes an EF Core projection regression where UseProjection over-selected all mapped columns for non-positional C# record entities by ensuring the instance-reuse heuristic does not treat the compiler-generated record copy constructor as a constructor-injection signal.

Changes:

  • Update QueryableProjectionScopeExtensions.ShouldReuseExistingInstance to ignore record copy constructors (protected R(R original)).
  • Add an EF+SQLite regression test asserting SQL only selects the requested column for a record entity.

Reviewed changes

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

File Description
src/HotChocolate/Data/test/Data.EntityFramework.Tests/IntegrationTests.cs Adds a regression test that captures generated SQL for a record entity projection and verifies only the selected column is projected.
src/HotChocolate/Data/src/Data/Projections/Expressions/QueryableProjectionScopeExtensions.cs Adjusts the “reuse existing instance” heuristic to exclude record copy constructors, preventing the selector from degrading into an identity projection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

UseProjection over-projects every column when the EF entity is a record

2 participants