Bug description
When using a ComplexCollection (JSON) mapping on an entity that is split across multiple tables using SplitToTable, queries that include the complex collection fail with:
System.InvalidOperationException: Sequence contains more than one element
Additional issues observed:
- Despite using Table splitting, the framework attempts to write data for the "Tags" collection to both tables
- The
[Column("tags")] attribute is ignored and the C# property name "Tags" is used instead for column mapping
Your code
#:package Microsoft.EntityFrameworkCore@10.0.5
#:package Microsoft.EntityFrameworkCore.Sqlite@10.0.5
#:property PublishAot=false
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.ComponentModel.DataAnnotations.Schema;
await using var conn = new SqliteConnection("Data Source=:memory:");
conn.Open();
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseSqlite(conn)
.EnableDetailedErrors()
.LogTo(Console.WriteLine, LogLevel.Information)
.Options;
await using (var ctx = new AppDbContext(options))
{
ctx.Database.EnsureCreated();
var post = new Post
{
Title = "Hello",
IsFeatured = true,
Tags =
[
new Tag { Name = "a" },
new Tag { Name = "b" }
]
};
ctx.Posts.Add(post);
await ctx.SaveChangesAsync();
}
await using (var ctx = new AppDbContext(options))
{
var data = await ctx.Posts
.AsNoTracking()
.Where(p => p.Tags.Any(t => t.Name.ToLower().Contains("a")))
.ToListAsync();
Console.WriteLine($"Posts count: {data.Count}");
}
[Table("posts")]
class Post
{
[Column("id")]
public int Id { get; set; }
[Column("title")]
public string? Title { get; set; }
[Column("is_featured")]
public bool IsFeatured { get; set; }
[Column("tags")]
public List<Tag> Tags { get; set; } = [];
}
class Tag
{
public string Name { get; set; } = string.Empty;
}
class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
{
public DbSet<Post> Posts => Set<Post>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>().HasKey(p => p.Id);
modelBuilder.Entity<Post>().ComplexCollection(p => p.Tags, c => c.ToJson());
modelBuilder.Entity<Post>().SplitToTable("posts_extra", tb =>
{
tb.Property(p => p.IsFeatured);
});
}
}
Stack traces
Unhandled exception. System.InvalidOperationException: Sequence contains more than one element
at System.Linq.ThrowHelper.ThrowMoreThanOneElementException()
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found)
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.GenerateJsonReader(Int32 jsonColumnIndex, ITypeBase structuralType)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessTopLevelComplexJsonProperties(StructuralTypeShaperExpression shaper, ParameterExpression instanceVariable, List`1 expressions)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.AddStructuralTypeInitialization(StructuralTypeShaperExpression shaper, ParameterExpression instanceVariable, List`1 variables, List`1 expressions)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.StructuralTypeMaterializerInjector.MaterializeEntity(StructuralTypeShaperExpression shaper, ParameterExpression materializationContextVariable, ParameterExpression concreteEntityTypeVariable, ParameterExpression instanceVariable, ParameterExpression entryVariable)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.StructuralTypeMaterializerInjector.ProcessStructuralTypeShaper(StructuralTypeShaperExpression shaper)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.StructuralTypeMaterializerInjector.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.StructuralTypeMaterializerInjector.Inject(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.InjectStructuralTypeMaterializers(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessShaper(Expression shaperExpression, Expression& relationalCommandResolver, 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.CreateQueryExecutorExpression[TResult](Expression query)
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.<ExecuteCore>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
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.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.<Main>$(String[] args)
at Program.<Main>$(String[] args)
at Program.<Main>$(String[] args)
at Program.<Main>(String[] args)
Verbose output
EF Core version
10.0.5
Database provider
Npgsql.EntityFrameworkCore.PostgreSQL, Microsoft.EntityFrameworkCore.Sqlite
Target framework
.NET 10.0
Operating system
No response
IDE
No response
Bug description
When using a ComplexCollection (JSON) mapping on an entity that is split across multiple tables using
SplitToTable, queries that include the complex collection fail with:System.InvalidOperationException: Sequence contains more than one elementAdditional issues observed:
[Column("tags")]attribute is ignored and the C# property name "Tags" is used instead for column mappingYour code
Stack traces
Verbose output
EF Core version
10.0.5
Database provider
Npgsql.EntityFrameworkCore.PostgreSQL, Microsoft.EntityFrameworkCore.Sqlite
Target framework
.NET 10.0
Operating system
No response
IDE
No response