Skip to content

Changes of nullable complex property with discriminator are not recognized #38119

@peterwurzinger

Description

@peterwurzinger

Bug description

Given an entity that contains a nullable complex property with a discriminator, changes of this nullable complex property away from null are not persisted - or at least not entirely.

To be precise, on a database level it seems, that the child-properties of that nullable complex properties are indeed saved, but the discriminator property stays unchanged. Subsequent reads of that instance therefore see the discriminator property with its empty-value, therefore assuming that the whole property isn't set at all and materializing it to null.

Your code

#:package Microsoft.EntityFrameworkCore.SqlServer@10.0.6
#:property PublishAot=false

using Microsoft.EntityFrameworkCore;

await using var context = new EntityContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();

var entity = new Entity();
context.Entities.Add(entity);

await context.SaveChangesAsync();
context.ChangeTracker.Clear();

entity = await context.Entities.SingleAsync();
entity.Prop = new OptionalComplexProperty()
{
  //The database column shows the "null" value
  OptionalValue = true
};

await context.SaveChangesAsync();
context.ChangeTracker.Clear();

entity = await context.Entities.SingleAsync();

//Should print "True", actually prints "null"
Console.WriteLine(entity.Prop?.ToString() ?? "null");

public class EntityContext : DbContext
{
  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Initial Catalog=DiscriminatorRepro;Integrated Security=true");

  public DbSet<Entity> Entities { get; set;} = null!;
  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    var entity = modelBuilder.Entity<Entity>();
    entity.HasKey(p => p.Id);

    var compl = entity.ComplexProperty(p => p.Prop);
    compl.HasDiscriminator();
  }
}

public class Entity
{
  public Guid Id { get; set; } = Guid.NewGuid();
  public OptionalComplexProperty? Prop { get; set; }
}

public class OptionalComplexProperty
{
  public bool? OptionalValue { get; set; }
}

Stack traces


Verbose output


EF Core version

10.0.6

Database provider

Microsoft.EntityFrameworkCore.SqlServer

Target framework

.NET 10

Operating system

Windows 11

IDE

No response

Metadata

Metadata

Type

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions