Table splitting + ConcurrencyToken throws unexpected DBConcurrencyException
When configuring multiple entities with table splitting and row version concurrency tokens, updating the dependents without the principal entity will throw an unexpected DbUpdateConcurrencyException.
If the principal entity (Foo) is tracked via ChangeTracker, then the updates persist properly. This occurs regardless of whether a transaction is used or not.
EF Configs:
//Principal
public class Foo
{
public string FooProp { get; set; }
public string FooId { get; set; } = Guid.NewGuid().ToString();
public Bar Bar { get; set; }
public Baz Baz { get; set; }
private class FooConfig : IEntityTypeConfiguration<Foo>
{
public void Configure(EntityTypeBuilder<Foo> builder)
{
builder.HasKey(p => p.FooId);
builder.HasOne(p => p.Bar).WithOne().HasForeignKey<Bar>(p => p.FooId);
builder.HasOne(p => p.Baz).WithOne().HasForeignKey<Baz>(p => p.FooId);
builder.Property<uint>("xmin").IsRowVersion();
builder.ToTable("Table");
}
}
}
//Dependent 1
public class Baz
{
public string Property1 { get; set; } = "prop1";
public string FooId { get; set; } = Guid.NewGuid().ToString();
private class BazConfig : IEntityTypeConfiguration<Baz>
{
public void Configure(EntityTypeBuilder<Baz> builder)
{
builder.HasKey(p => p.FooId);
builder.Property<uint>("xmin").IsRowVersion();
builder.ToTable("Table");
}
}
}
//Dependent 2
public class Bar
{
public string Property2 { get; set; } = "prop2";
public string FooId { get; set; } = Guid.NewGuid().ToString();
private class BarConfig : IEntityTypeConfiguration<Bar>
{
public void Configure(EntityTypeBuilder<Bar> builder)
{
builder.HasKey(p => p.FooId);
builder.Property<uint>("xmin").IsRowVersion();
builder.ToTable("Table");
}
}
}
Include provider and version information
EF Core version: Database provider: Postgresql Target framework: .NET 8 Operating system: WIN 10 IDE:VS 2022
@Westboldyi can you please submit a minimal, runnable console program that shows the error happening? It's hard to piece together exactly what you're doing from a screenshot and partial snippets.
Reproduction using postgres 14: https://github.com/Westboldyi/XminOrderByRepro/tree/table-splitting-db-concurrency
I believe this is by-design. @AndriySvyryd can you confirm that we require the principal to be tracked for this case?
No, this is a bug. We need to either collapse both updates into one command (by indexing using key values instead of entries) or to separate the two commands in different batches.