I'm running efcore 2.0.1.
I have a model:
public class BigAwesomeDinosaurWithTeeth
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public ICollection<YummyPunyPrey> YummyPunyPrey { get; set; }
}
public class YummyPunyPrey
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public Guid? BigAwesomeDinosaurWithTeethId { get; set; }
[ForeignKey("BigAwesomeDinosaurWithTeethId")]
public BigAwesomeDinosaurWithTeeth BigAwesomeDinosaurWithTeeth { get; set; }
}
I have no fluent api on these two classes. But when I generate a migration
constraints: table =>
{
table.PrimaryKey("PK_YummyPunyPrey", x => x.Id);
table.ForeignKey(
name: "FK_YummyPunyPrey_BigAwesomeDinosaurWithTeeth_BigAwesomeDinosaurWithTeethId",
column: x => x.BigAwesomeDinosaurWithTeethId,
principalTable: "BigAwesomeDinosaurWithTeeth",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
Why is it generating onDelete: ReferentialAction.Restrict when the documentation says it should handle it as a ClientSetNull
https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete
Behavior Name | Effect on dependent/child in memory | Effect on dependent/child in database
ClientSetNull (Default) | Foreign key properties are set to null | None
Changes in EF Core 2.0: In previous releases, Restrict would cause optional foreign key properties in tracked dependent entities to be set to null, and was the default delete behavior for optional relationships. In EF Core 2.0, the ClientSetNull was introduced to represent that behavior and became the default for optional relationships. The behavior of Restrict was adjusted to never have any side effects on dependent entities.
Any help as to why this is happening would be much appreciated.
EF Core 2.0.1 metadata and migrations use different enums for specifying the delete behavior - respectively DeleteBehavior
and ReferentialAction
. While the first is well documented, the second and the mapping between the two is not (at the time of writing).
Here is the current mapping:
DeleteBehavior ReferentialAction
============== =================
Cascade Cascade
ClientSetNull Restrict
Restrict Restrict
SetNull SetNull
In your case, the relationship is optional, hence the DeleteBehavior
by convention is ClientSetNull
which maps to onDelete: Restrict
, or in other words, enforced (enabled) FK w/o cascade delete.
If you want different behavior, you have to use fluent API, e.g.
modelBuilder.Entity<BigAwesomeDinosaurWithTeeth>()
.HasMany(e => e.YummyPunyPrey)
.WithOne(e => e.BigAwesomeDinosaurWithTeeth)
.OnDelete(DeleteBehavior.SetNull); // or whatever you like