Skip to content

Fix struct complex type boxing in collection materialization#37934

Merged
roji merged 3 commits intodotnet:mainfrom
roji:fix/37926-struct-complex-type-boxing
Mar 17, 2026
Merged

Fix struct complex type boxing in collection materialization#37934
roji merged 3 commits intodotnet:mainfrom
roji:fix/37926-struct-complex-type-boxing

Conversation

@roji
Copy link
Copy Markdown
Member

@roji roji commented Mar 16, 2026

When projecting a struct complex type alongside a collection navigation, CompensateForCollectionMaterialization added the value-type expression to _valuesArrayInitializers without boxing, causing NewArrayInit(typeof(object), ...) to throw:

InvalidOperationException: An expression of type 'Outer' cannot be used to initialize an array of type 'System.Object'

The fix boxes value types before adding to the object[] array, matching the existing pattern in the scalar projection path.

Fixes #37926

@roji roji requested a review from a team as a code owner March 16, 2026 12:03
Copilot AI review requested due to automatic review settings March 16, 2026 12:03
@roji roji enabled auto-merge (squash) March 16, 2026 12:04
Copy link
Copy Markdown

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

Fixes a regression in relational query shaper compilation where projecting a value-type (struct) complex property alongside a collection navigation could add an unboxed value-type expression into an object[] initializer, causing Expression.NewArrayInit to throw at runtime. Adds coverage to prevent recurrence across providers.

Changes:

  • Box value-type expressions before adding them to the internal object[] value buffer used during collection materialization.
  • Add a specification regression test reproducing the struct complex type + entity collection navigation projection scenario (#37926).
  • Add provider-specific overrides/baselines (SQL Server) and a Cosmos override for the new test.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs Boxes value-type parameters before storing them in _valuesArrayInitializers during collection materialization compensation.
test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs Adds regression test for projecting a struct complex property together with an entity collection navigation.
test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs Overrides the new test to assert the expected SQL baseline on SQL Server.
test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs Adds an override for the new test (currently implemented as a no-op completion).

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 16, 2026 14:46
Copy link
Copy Markdown

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

Fixes a regression in EF Core’s relational query materialization pipeline where projecting a struct complex type alongside a collection navigation could fail due to missing boxing when building an object[] used during collection materialization.

Changes:

  • Box value-type projection expressions before adding them to the object[] initializer list used during collection materialization compensation.
  • Add a new specification test covering struct complex type + entity collection navigation projection.
  • Add provider-specific overrides: SQL Server SQL baseline assertion; Cosmos override asserting translation failure.

Reviewed changes

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

File Description
src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs Boxes value types before storing them in the object[] used for collection materialization compensation.
test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs Adds regression test for projecting a struct complex property alongside an entity collection navigation.
test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs Overrides the new test and asserts the generated SQL baseline on SQL Server.
test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs Overrides the new test to assert translation failure (collection navigations across documents unsupported).

You can also share your feedback on Copilot code review. Take the survey.

@AndriySvyryd AndriySvyryd assigned roji and unassigned AndriySvyryd Mar 16, 2026
roji and others added 2 commits March 17, 2026 00:09
When projecting a struct complex type alongside a collection navigation,
CompensateForCollectionMaterialization added the value-type expression to
_valuesArrayInitializers without boxing, causing NewArrayInit(typeof(object), ...)
to throw InvalidOperationException.

Box value types before adding to the object[] array, matching the existing
pattern in the scalar projection path.

Fixes dotnet#37926

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…override

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@roji roji force-pushed the fix/37926-struct-complex-type-boxing branch from bb1c9ac to 24e46fc Compare March 16, 2026 23:09
Cosmos doesn't support entity collection navigations across separate
documents (requires relational LEFT JOIN), so skip the test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 17, 2026 13:59
Copy link
Copy Markdown

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

Fixes a regression in relational query compilation where projecting a value-type (struct) complex type alongside a collection navigation could cause expression tree array initialization to fail due to missing boxing, and adds a regression test to cover the scenario.

Changes:

  • Box value-type expressions before adding them to the object[] used during collection materialization compensation in the relational shaper visitor.
  • Add a new specification test covering projection of a struct complex type together with an entity collection navigation.
  • Add/adjust provider overrides (SQL Server asserts SQL; Cosmos skips due to unsupported cross-document collection navigations).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs Ensures value-type parameters are boxed before being added to the object[] initializer used during collection materialization.
test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs Adds the cross-projection regression test for struct complex type + entity collection navigation.
test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs Overrides the new test to assert the expected SQL on SQL Server.
test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs Overrides the new test to skip (Cosmos limitation for cross-document entity collection navigations).

You can also share your feedback on Copilot code review. Take the survey.

@roji roji merged commit 39beebf into dotnet:main Mar 17, 2026
14 checks passed
@roji roji deleted the fix/37926-struct-complex-type-boxing branch March 17, 2026 15:11
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.

Regression: LINQ Select with struct ComplexProperty + collection navigation throws InvalidOperationException

3 participants