Bug description
When configuring an entity that contains both
- a nullable complex property needing a discriminator and
- a shadow property
querying tracked instances of the configured entity throws an ArgumentOutOfRangeException. A quick inspection with Source Link indicates, that it somehow seems to lose track of the Discriminator property in ShadowValuesFactoryFactory.CreateReadShadowValueExpression, as only the manually configured shadow properties are present.
For context:
I encountered the problem with a real-life complex property that consisted of optional/nullable properties only, in combination with an entity-level Audit that would be applied to entities meeting a certain criteria by convention. So the use case is not too exotic.
I tried to reproduce it as concise as possible using the InMemory provider, but I observed the problem with the SqlServer provider as well. I think it's a provider-agnostic issue anyways.
Your code
#:package Microsoft.EntityFrameworkCore.InMemory@10.0.1
#:property PublishAot=false
using Microsoft.EntityFrameworkCore;
await using var context = new EntityContext();
await context.Database.EnsureCreatedAsync();
//Throws ArgumentOutOfRangeException
var entities = await context.Entities.ToArrayAsync();
public class EntityContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseInMemoryDatabase("ComplexPropertyRepro");
public DbSet<Entity> Entities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var entity = modelBuilder.Entity<Entity>();
entity.Property(p => p.Id);
entity.HasKey(p => p.Id);
var compl = entity.ComplexProperty(p => p.Prop);
compl.Property(p => p.OptionalValue);
compl.HasDiscriminator();
//Imagine this being added via convetion to prepare some kind of entity-level audit
entity.Property<string>("CreatedBy").IsRequired(false);
}
}
public class Entity
{
public Guid Id { get; set; }
public OptionalComplexProperty? Prop { get; set; }
}
public class OptionalComplexProperty
{
public bool? OptionalValue { get; set; }
}
Stack traces
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at System.SZArrayHelper.get_Item[T](Int32 index)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ShadowValuesFactoryFactory.CreateReadShadowValueExpression(Expression parameter, IPropertyBase property)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ShadowValuesFactoryFactory.CreateReadValueExpression(Expression parameter, IPropertyBase property)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SnapshotFactoryFactory.CreateSnapshotExpression(Type clrType, Expression parameter, Type[] types, IList`1 propertyBases)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SnapshotFactoryFactory.CreateConstructorExpression(IRuntimeTypeBase structuralType, Expression parameter)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.StructuralTypeMaterializerInjector.CreateFullMaterializeExpression(ITypeBase concreteStructuralType, ValueTuple`5 materializeExpressionContext)
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.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.ShaperExpressionProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.ShaperExpressionProcessingExpressionVisitor.ProcessShaper(Expression shaperExpression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.VisitShapedQuery(ShapedQueryExpression shapedQueryExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.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 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)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToArrayAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.<Main>$(String[] args) in E:\ComplexPropertyRepro\Program.cs:line 10
at Program.<Main>$(String[] args) in E:\ComplexPropertyRepro\Program.cs:line 10
at Program.<Main>(String[] args)
Verbose output
EF Core version
10.0.1
Database provider
Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.InMemory
Target framework
net10.0
Operating system
Windows 11
IDE
Visual Studio 2026 and .NET SDK on CLI
Bug description
When configuring an entity that contains both
querying tracked instances of the configured entity throws an ArgumentOutOfRangeException. A quick inspection with Source Link indicates, that it somehow seems to lose track of the Discriminator property in
ShadowValuesFactoryFactory.CreateReadShadowValueExpression, as only the manually configured shadow properties are present.For context:
I encountered the problem with a real-life complex property that consisted of optional/nullable properties only, in combination with an entity-level Audit that would be applied to entities meeting a certain criteria by convention. So the use case is not too exotic.
I tried to reproduce it as concise as possible using the InMemory provider, but I observed the problem with the SqlServer provider as well. I think it's a provider-agnostic issue anyways.
Your code
Stack traces
Verbose output
EF Core version
10.0.1
Database provider
Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.InMemory
Target framework
net10.0
Operating system
Windows 11
IDE
Visual Studio 2026 and .NET SDK on CLI