Invalid reference between parent and child entities
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
We are using EF Core 8.0.6 and observe strange reference assignment when trying to save hierarchy of objects. We have next structure: Entity, Child Entity and CustomAttribute. Entity has multiple CustomAttributes and multiple ChildEntities. ChildEntity has multiple CustomAttributes. CustomAttribute for both Entity and ChildEntity is the same class. Whenever we save hierarchy of objects EF Core merges CustomAttributes for Entity and FIRST(literally first) ChildEntity. Please see code below and result
```C#
internal class Program
{
static async Task Main(string[] args)
{
await using var context = new MyContext();
var newEntity = new Entity
{
Name = "EntityName",
CustomAttributes = new Collection
{
new CustomAttribute{ Value = 1, Type = "Entity" },
},
ChildEntities =
[
new ChildEntity
{
Name = "ChildEntity1",
CustomAttributes = new Collection
{
new CustomAttribute { Value = 1000, Type = "ChildEntity" },
},
},
new ChildEntity
{
Name = "ChildEntity2",
CustomAttributes = new Collection
{
new CustomAttribute { Value = 10000, Type = "ChildEntity" },
},
}
]
};
context.Entities.Add(newEntity);
await context.SaveChangesAsync();
Console.WriteLine("Hello, World!");
}
}
public class Entity
{
public int Id { get; set; }
public string Name { get; set; }
public Collection ChildEntities { get; set; }
public Collection CustomAttributes { get; set; }
}
public class ChildEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public Entity Entity { get; set; }
public Collection CustomAttributes { get; set; }
}
public class CustomAttribute
{
public int Id { get; set; }
public int ReferenceId { get; set; }
public int Value { get; set; }
public string Type { get; set; }
}
public class MyContext : DbContext
{
public DbSet Entities { get; set; }
public DbSet ChildEntities { get; set; }
public DbSet CustomAttributes { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.LogTo(Console.WriteLine).EnableSensitiveDataLogging();
options.UseSqlServer("Server=localhost;Database=Test;Integrated Security=true;TrustServerCertificate=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity().ToTable("Entity");
modelBuilder.Entity().HasKey(p => p.Id);
modelBuilder.Entity().ToTable("ChildEntity");
modelBuilder.Entity().HasKey(p => p.Id);
modelBuilder.Entity().ToTable("CustomAttribute");
modelBuilder.Entity().HasKey(p => p.Id);
modelBuilder.Entity().HasMany(p => p.ChildEntities).WithOne(p => p.Entity).HasForeignKey(ss => ss.ParentId);
modelBuilder.Entity().HasMany(p => p.CustomAttributes).WithOne().HasForeignKey(ss => ss.ReferenceId).HasPrincipalKey(p => p.Id);
modelBuilder.Entity().HasMany(p => p.CustomAttributes).WithOne().HasForeignKey(ss => ss.ReferenceId).HasPrincipalKey(p => p.Id);
}
}
```
And result in database:
Entity and ChildEntity tables are good, problem in CustomAttribute. There is corruption in CustomAttribute for first child entity(record with Id 1 on above screenshot), it has value from first ChildEntity, but id of parent Entity
What's more, problem occurs on adding entity to context, not on saving it, looks like Entity and FIRST ChildEntity reference same merged collection of CustomAttributes:
### Expected results
- Save all objects properly
- Throw exception if given setup is not possible
### Workarounds which work
- Save Entity and ChildEntity separately
- Implement inheritance for CustomAttributes to separate classes for Entity and ChildEntity
### Include provider and version information
EF Core version: 8.0.6
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Target framework: (e.g. .NET 8.0)
Operating system: Windows 11
IDE: (e.g. Visual Studio 2022 17.10.1)
Contributor guide
Assessment
This issue has not been assessed yet.