web-dev-qa-db-fra.com

Paramètre de relation nullable EFCore onDelete: ReferentialAction.Restrict

J'utilise efcore 2.0.1.

J'ai un modèle:

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; }

}

Je n'ai pas d'api couramment sur ces deux classes. Mais quand je génère une 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);
            });

Pourquoi génère-t-il onDelete: ReferentialAction.Restrict alors que la documentation indique qu'il doit le gérer comme un ClientSetNull

https://docs.Microsoft.com/en-us/ef/core/saving/cascade-delete

Nom du comportement | Effet sur la personne à charge/l'enfant en mémoire | Effet sur la personne à charge/enfant dans la base de données

ClientSetNull (par défaut) | Les propriétés de la clé étrangère sont définies sur null | Aucune

Modifications dans EF Core 2.0: dans les versions précédentes, Restreindre entraînait la valeur null des propriétés de clé étrangère facultatives dans les entités dépendantes suivies et était le comportement de suppression par défaut pour les relations facultatives. Dans EF Core 2.0, ClientSetNull a été introduit pour représenter ce comportement et est devenu la valeur par défaut pour les relations facultatives. Le comportement de Restrict a été ajusté pour ne jamais avoir d'effets secondaires sur les entités dépendantes.

Toute aide expliquant pourquoi cela se produit serait très appréciée.

13
David Moores

Les métadonnées et migrations EF Core 2.0.1 utilisent des énumérations différentes pour spécifier le comportement de suppression - respectivement DeleteBehavior et ReferentialAction . Alors que le premier est bien documenté, le second et la correspondance entre les deux ne le sont pas (au moment de la rédaction).

Voici la cartographie actuelle:

DeleteBehavior    ReferentialAction
==============    =================
Cascade           Cascade
ClientSetNull     Restrict
Restrict          Restrict
SetNull           SetNull

Dans votre cas, la relation est facultative , d'où le DeleteBehavior par convention est ClientSetNull qui correspond à onDelete: Restrict, ou en d'autres termes, forcé (activé) FK sans suppression en cascade.

Si vous souhaitez un comportement différent, vous devez utiliser une API fluide, par exemple.

modelBuilder.Entity<BigAwesomeDinosaurWithTeeth>()
    .HasMany(e => e.YummyPunyPrey)
    .WithOne(e => e.BigAwesomeDinosaurWithTeeth)
    .OnDelete(DeleteBehavior.SetNull); // or whatever you like
20
Ivan Stoev