-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Open
Labels
Description
Bug description
Calling EntityEntry.ReloadAsync() on an entity with a nullable complex property throws an InvalidOperationException when the complex property is null.
In the repro below, Product.Price is configured as optional, but reloading the entity fails because EF attempts to materialize required members (Amount, CurrencyId) of the complex type even though the complex property itself is null.
Your code
#:package Npgsql.EntityFrameworkCore.PostgreSQL@10.0.0
#:package Microsoft.EntityFrameworkCore.Relational@10.0.2
#:property PublishAot=false
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
await using var context = new ProductContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
context.Products.Add(new());
await context.SaveChangesAsync();
await context.ChangeTracker.Entries().First().ReloadAsync();
;
public sealed class ProductContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql("Host=localhost;Username=postgres;Password=postgres;Database=Test")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Product>().ComplexProperty(x => x.Price, x =>
{
x.IsRequired(false);
});
}
public sealed class Product
{
public int Id { get; private set; }
public Price? Price { get; set; }
}
public sealed class Price
{
public required decimal Amount { get; init; }
public required int CurrencyId { get; init; }
}Stack traces
An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'The property 'Amount' contains null on entity 'Product' with the key value '{Amount: 0}', but the property is marked as required.'
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.HandleConceptualNulls(Boolean sensitiveLoggingEnabled, Boolean force, Boolean isCascadeDelete)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntryBase.HandleNullForeignKey(IProperty property, Boolean setModified, Boolean isCascadeDelete)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntryBase.SetProperty(IPropertyBase propertyBase, Object value, Boolean isMaterialization, Boolean setModified, Boolean isCascadeDelete, CurrentValueType valueType)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntryBase.SetProperty(IPropertyBase propertyBase, Object value, Boolean isMaterialization, Boolean setModified, Boolean isCascadeDelete)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntryBase.set_Item(IPropertyBase propertyBase, Object value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.CurrentPropertyValues.SetValueInternal(IInternalEntry entry, IPropertyBase property, Object value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntryPropertyValues.SetValues(PropertyValues propertyValues)
at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.Reload(PropertyValues storeValues)
at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.<ReloadAsync>d__54.MoveNext()
Verbose output
EF Core version
10.0.2
Database provider
Npgsql.EntityFrameworkCore.PostgreSQL
Target framework
.NET 10.0.2
Operating system
Windows 11
IDE
VSCode