Regression: LINQ Select with struct ComplexProperty + collection navigation throws InvalidOperationException
Upgrading from EF Core 11.0.0-preview.1 to 11.0.0-preview.2 introduces a regression when a LINQ Select projection combines:
- A collection navigation whose elements have a
readonly record structComplexProperty projected via constructor - A struct ComplexProperty with nested struct ComplexProperties projected via constructor on the same entity
Either projection works individually. When combined in the same Select, EF Core throws:
InvalidOperationException: An expression of type 'Outer' cannot be used to initialize an array of type 'System.Object'
The stack trace points to ShaperProcessingExpressionVisitor.ProcessProjection calling LiftComplexTypeToNewArray, which appears new in preview.2 and does not box the struct before adding it to the object[] array initializer expression.
Reproduces on both SQLite and PostgreSQL — this is an EF Core core issue, not provider-specific.
#:package Microsoft.EntityFrameworkCore@11.0.0-preview.2.26159.112
#:package Microsoft.EntityFrameworkCore.Sqlite@11.0.0-preview.2.26159.112
using Microsoft.EntityFrameworkCore;
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseSqlite("Data Source=:memory:")
.Options;
using var db = new AppDbContext(options);
db.Database.OpenConnection();
db.Database.EnsureCreated();
var parentId = Guid.NewGuid();
db.Parents.Add(new Parent
{
Id = parentId,
Name = "P1",
Coords = new Outer
{
First = new Inner { A = "1", B = "2" },
Second = new Inner { A = "3", B = "4" }
},
Children = [new Child { Id = Guid.NewGuid(), ParentId = parentId, Data = new Inner { A = "x", B = "y" } }]
});
db.SaveChanges();
// Works in preview.1, throws in preview.2
var result = await db.Parents
.AsNoTracking()
.Where(p => p.Id == parentId)
.Select(p => new ParentVm(
p.Name,
p.Children.Select(c => new ChildVm(new InnerVm(c.Data))).ToList(), // collection nav + struct
new OuterVm(p.Coords) // nested struct
))
.FirstOrDefaultAsync();
Console.WriteLine(result);
// ── Domain ──────────────────────────────────────────────────────────
public readonly record struct Inner
{
public string? A { get; init; }
public string? B { get; init; }
}
public readonly record struct Outer
{
public Inner First { get; init; }
public Inner Second { get; init; }
}
public class Child
{
public Guid Id { get; set; }
public Guid ParentId { get; set; }
public Inner Data { get; set; }
public Parent? Parent { get; set; }
}
public class Parent
{
public Guid Id { get; set; }
public string Name { get; set; } = default!;
public Outer Coords { get; set; }
public List<Child> Children { get; set; } = [];
}
// ── View models ─────────────────────────────────────────────────────
public record InnerVm(string? A, string? B)
{
public InnerVm(Inner i) : this(i.A, i.B) { }
}
public record OuterVm(InnerVm First, InnerVm Second)
{
public OuterVm(Outer o) : this(new InnerVm(o.First), new InnerVm(o.Second)) { }
}
public record ChildVm(InnerVm Data);
public record ParentVm(string Name, List<ChildVm> Children, OuterVm Coords);
// ── DbContext ───────────────────────────────────────────────────────
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
{
public DbSet<Parent> Parents => Set<Parent>();
public DbSet<Child> Children => Set<Child>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>(e =>
{
e.HasKey(x => x.Id);
e.ComplexProperty(x => x.Coords, c =>
{
c.ComplexProperty(x => x.First, f =>
{
f.Property(x => x.A).HasColumnName("first_a");
f.Property(x => x.B).HasColumnName("first_b");
});
c.ComplexProperty(x => x.Second, s =>
{
s.Property(x => x.A).HasColumnName("second_a");
s.Property(x => x.B).HasColumnName("second_b");
});
});
e.HasMany(x => x.Children).WithOne(x => x.Parent).HasForeignKey(x => x.ParentId);
});
modelBuilder.Entity<Child>(e =>
{
e.HasKey(x => x.Id);
e.ComplexProperty(x => x.Data, d =>
{
d.Property(x => x.A).HasColumnName("data_a");
d.Property(x => x.B).HasColumnName("data_b");
});
});
}
}Query completes and returns ParentVm { Name = P1, Children = [...], Coords = OuterVm { ... } } (as it does on preview.1).
Throws InvalidOperationException during query compilation.
System.InvalidOperationException: An expression of type 'Outer' cannot be used to initialize an array of type 'System.Object'
at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable`1 initializers)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<ProcessProjection>g__LiftComplexTypeToNewArray|19_1(Expression expression, Type newArrayType)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessProjection(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessProjection(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessShaper(Expression shaperExpression, RelationalCommandCache& relationalCommandCache, IReadOnlyList`1& readerColumns, LambdaExpression& relatedDataLoaders, Int32& collectionId)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQuery(ShapedQueryExpression shapedQueryExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
No response
11.0.0-preview.2.26159.112 (regression from 11.0.0-preview.1.26104.118)
Reproduces on both:
- Microsoft.EntityFrameworkCore.Sqlite 11.0.0-preview.2
- Npgsql.EntityFrameworkCore.PostgreSQL 11.0.0-preview.2
.NET 11.0
Windows 11
Visual Studio 2022