efcore
efcore copied to clipboard
EntityBuilder: .OnDelete() is ignored if used after .IsRequired() and shadow property
Problem
When configuring a non-nullable foreign key with FluentAPI .OnDelete() is ignored when called after .IsRequired() but only if no explicit foreign key is configured for relationship in dependant entity. If I'd add a AddressId property in Order model it would work as expected.
Code
Model
public class Address {
public int AddressId { get; set; }
}
public class Order {
public int OrderId { get; set; }
public Address Address { get; set; }
}
FluentAPI Case 1) Does work: DeleteBehavior: No Action is taken (see debug output below) Case 2) Doesn't work: Default behavior Cascade is taken (see debug output below)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 1) Does work
modelBuilder.Entity<Order>()
.HasOne(o => o.Address)
.WithOne()
.HasForeignKey<Order>("AddressId")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
// 2) Doesn't work
modelBuilder.Entity<Order>()
.HasOne(o => o.Address)
.WithOne()
.HasForeignKey<Order>("AddressId")
.IsRequired()
.OnDelete(DeleteBehavior.NoAction);
}
Debug ShortView Case 1
Model:
EntityType: Address
Properties:
AddressId (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
Keys:
AddressId PK
EntityType: Order
Properties:
OrderId (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
AddressId (no field, int) Shadow Required FK Index
Navigations:
Address (Address) ToPrincipal Address
Keys:
OrderId PK
Foreign keys:
Order {'AddressId'} -> Address {'AddressId'} Unique ToPrincipal: Address
Indexes:
AddressId Unique
Case 2
Model:
EntityType: Address
Properties:
AddressId (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
Keys:
AddressId PK
EntityType: Order
Properties:
OrderId (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
AddressId (no field, int) Shadow Required FK Index
Navigations:
Address (Address) ToPrincipal Address
Keys:
OrderId PK
Foreign keys:
Order {'AddressId'} -> Address {'AddressId'} Unique ToPrincipal: Address Cascade
Indexes:
AddressId Unique
Maybe also see a similar yet fixed issue #23555, but it was the other way around (.IsRequired didn't work after .OnDelete)
EF Core version: 5.0.7 Database provider: Microsoft.EntityFrameworkCore.SqlServer / Microsoft.EntityFrameworkCore.SQlite / ... ? Target framework: NET 5.0 Operating system: Win10.0.19042.1052 IDE: Visual Studio 2019 CE 16.10
The issue is still present. https://github.com/dotnet/efcore/blob/289e7a69b0c02f5569bbaf0ac353c21afde5e397/src/EFCore/Metadata/Internal/ForeignKey.cs#L687-L689
When changing required, the convention return new Fk to change deletebehavior to cascade but we don't pick up new FK and hence DeleteBehavior is applied on stale fk and lost.
We need to start a convention batch and track the FK when the conventions need to run