diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs index 4735489a932..cbd03fd935b 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs @@ -1479,7 +1479,13 @@ Expression CompensateForCollectionMaterialization(ParameterExpression parameter, { if (_containsCollectionMaterialization) { - _valuesArrayInitializers!.Add(parameter); + var expressionToAdd = (Expression)parameter; + if (expressionToAdd.Type.IsValueType) + { + expressionToAdd = Convert(expressionToAdd, typeof(object)); + } + + _valuesArrayInitializers!.Add(expressionToAdd); return Convert( ArrayIndex( _valuesArrayExpression!, diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs index e92b46d76d0..b75dee268f4 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionCosmosTest.cs @@ -221,6 +221,10 @@ FROM root c } + // Cosmos doesn't support entity collection navigations across documents + public override Task Project_struct_complex_type_with_entity_collection_navigation() + => Task.CompletedTask; + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs b/test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs index 2b4a2cb253e..2f992282095 100644 --- a/test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/Associations/ComplexProperties/ComplexPropertiesCollectionTestBase.cs @@ -5,4 +5,70 @@ namespace Microsoft.EntityFrameworkCore.Query.Associations.ComplexProperties; public abstract class ComplexPropertiesCollectionTestBase(TFixture fixture) : AssociationsCollectionTestBase(fixture) - where TFixture : ComplexPropertiesFixtureBase, new(); + where TFixture : ComplexPropertiesFixtureBase, new() +{ + #region 37926 + + [ConditionalFact] + public virtual async Task Project_struct_complex_type_with_entity_collection_navigation() + { + var contextFactory = await InitializeNonSharedTest( + seed: async context => + { + context.Add(new Context37926.Parent + { + Id = 1, + Coords = new Context37926.Coords { X = 1, Y = 2 }, + Children = [new() { Id = 1, Name = "Child1" }] + }); + await context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var result = await context.Set() + .OrderBy(p => p.Id) + .Select(p => new { p.Coords, p.Children }) + .FirstAsync(); + + Assert.Equal(1, result.Coords.X); + Assert.Single(result.Children); + } + + protected class Context37926(DbContextOptions options) : DbContext(options) + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(b => + { + b.Property(e => e.Id).ValueGeneratedNever(); + b.ComplexProperty(e => e.Coords); + b.HasMany(e => e.Children).WithOne().HasForeignKey(c => c.ParentId); + }); + + modelBuilder.Entity().Property(e => e.Id).ValueGeneratedNever(); + } + + public class Parent + { + public int Id { get; set; } + public Coords Coords { get; set; } + public List Children { get; set; } = []; + } + + public struct Coords + { + public int X { get; set; } + public int Y { get; set; } + } + + public class Child + { + public int Id { get; set; } + public required string Name { get; set; } + public int ParentId { get; set; } + } + } + + #endregion 37926 +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs index 23d6d89e192..7e7c4f68595 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Associations/ComplexJson/ComplexJsonCollectionSqlServerTest.cs @@ -352,6 +352,23 @@ FROM [RootEntity] AS [r] } } + public override async Task Project_struct_complex_type_with_entity_collection_navigation() + { + await base.Project_struct_complex_type_with_entity_collection_navigation(); + + AssertSql( + """ +SELECT [p0].[Coords_X], [p0].[Coords_Y], [p0].[Id], [c].[Id], [c].[Name], [c].[ParentId] +FROM ( + SELECT TOP(1) [p].[Coords_X], [p].[Coords_Y], [p].[Id] + FROM [Parent] AS [p] + ORDER BY [p].[Id] +) AS [p0] +LEFT JOIN [Child] AS [c] ON [p0].[Id] = [c].[ParentId] +ORDER BY [p0].[Id] +"""); + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType());