Skip to content

Entity splitting with Complex Property throws InvalidOperationException #38077

@mathiasschaemelhout

Description

@mathiasschaemelhout

Bug description

When using a Complex Property on an entity that is split across multiple tables using SplitToTable, queries that include the complex property fail with:

System.InvalidOperationException: Sequence contains more than one element

Might be related to #37982, but this example does not use JSON or collections.

Your code

using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

async Task Main()
{
  await using var context = new TestContext();
  await context.Database.EnsureDeletedAsync();
  await context.Database.EnsureCreatedAsync();

  var hooks = await context.Set<Hook>().ToListAsync();
  Console.WriteLine($"Hooks count: {hooks.Count}");
}

public class TestContext : DbContext
{
  private const string ConnectionString = "Server=localhost,1433;Database=Test;";

  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlServer(ConnectionString);

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Hook>().HasKey(hook => hook.Id);
    modelBuilder.Entity<Hook>().ComplexProperty(hook => hook.Number); // This seems to be causing the issue

    modelBuilder.Entity<Hook>().SplitToTable(
        "HookMetadata",
        tableBuilder =>
        {
          tableBuilder.Property(hook => hook.Id).HasColumnName("HookId");
          tableBuilder.Property(hook => hook.Weight);
          tableBuilder.Property(hook => hook.IsTestHook);
        });
  }
}

public class Hook
{
  public int Id { get; set; }
  public DateTime CreatedOn { get; set; }
  public HookNumber Number { get; set; }

  // Metadata
  public decimal? Weight { get; set; }
  public bool? IsTestHook { get; set; }
}

public class HookNumber
{
  public string Raw { get; set; }
  public long Parsed { get; set; }
}

Stack traces

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.Single[TSource](IEnumerable`1 source)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.GenerateComplexPropertyShaperExpression(StructuralTypeProjectionExpression containerProjection, IComplexProperty complexProperty)
   at Microsoft.EntityFrameworkCore.Query.StructuralTypeProjectionExpression.BindComplexProperty(IComplexProperty complexProperty)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.<ApplyProjection>g__ProcessType|62_19(StructuralTypeProjectionExpression typeProjection, <>c__DisplayClass62_6&)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.<ApplyProjection>g__AddStructuralTypeProjection|62_0(StructuralTypeProjectionExpression projection)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ApplyProjection(Expression shaperExpression, ResultCardinality resultCardinality, QuerySplittingBehavior querySplittingBehavior)
   at Microsoft.EntityFrameworkCore.Query.Internal.SelectExpressionProjectionApplyingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPostprocessor.Process(Expression query)
   at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerQueryTranslationPostprocessor.Process(Expression query)
   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 Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Collections.Generic.IAsyncEnumerable<TEntity>.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

Verbose output


EF Core version

10.0.5

Database provider

Microsoft.EntityFrameworkCore.SqlServer

Target framework

.NET 10

Operating system

Windows 11

IDE

No response

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions