Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EFCore nullable relationship setting onDelete: ReferentialAction.Restrict

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.

like image 623
David Moores Avatar asked Jan 30 '18 12:01

David Moores


People also ask

How do I remove a one to many relationship in Entity Framework?

after manual set the property,single call to "dbContext. As. Remove(someA)" work as expected!

What is DeleteBehavior Cascade?

DeleteBehavior.Cascade – Delete the child when the parent is deleted (e.g. Cascading deletes) DeleteBehavior.SetNull – Set the FK on the child to just be null (So allow orphans) DeleteBehavior.Restrict – Don't allow the parent to be deleted at all.

How do I enable cascade delete in Entity Framework?

Cascade delete automatically deletes dependent records or sets null to ForeignKey columns when the parent record is deleted in the database. Cascade delete is enabled by default in Entity Framework for all types of relationships such as one-to-one, one-to-many and many-to-many.


1 Answers

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
like image 179
Ivan Stoev Avatar answered Oct 02 '22 15:10

Ivan Stoev