Skip to content

Fix struct complex type boxing in collection materialization#37934

Open
roji wants to merge 2 commits intodotnet:mainfrom
roji:fix/37926-struct-complex-type-boxing
Open

Fix struct complex type boxing in collection materialization#37934
roji wants to merge 2 commits intodotnet:mainfrom
roji:fix/37926-struct-complex-type-boxing

Conversation

@roji
Copy link
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

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

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
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