web-dev-qa-db-fra.com

Entity Framework Core en cascade supprimer une relation à plusieurs

public class Station : IEntitie
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public virtual ICollection<RegulatorySchedule> RegulatoryScheduleDispatchStations { get; set; }    

    public virtual ICollection<RegulatorySchedule> RegulatoryScheduleDestinationStations { get; set; }   
}

public class RegulatorySchedule : IEntitie
{
    [Key]
    public int Id { get; set; }

    public virtual Station DispatchStation { get; set; }      

    public virtual Station DestinationStation { get; set; }     
}


protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        modelBuilder.Entity<RegulatorySchedule>()
            .HasOne(s => s.DestinationStation)
            .WithMany(s => s.RegulatoryScheduleDestinationStations)
            .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);

        modelBuilder.Entity<RegulatorySchedule>()
            .HasOne(s => s.DispatchStation)
            .WithMany(s => s.RegulatoryScheduleDispatchStations)
            .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
}

La base de données est créée lors de la migration uniquement lorsque j'expose clairement le comportement lors de la suppression de Restrict OnDelete (Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict). Sinon, elle génère une exception:

"Introduction de la contrainte FOREIGN KEY 'FK_RegulatorySchedules_Stations_DispatchStationId' sur la table 'RegulatorySchedules' peut provoquer des cycles ou plusieurs chemins en cascade. . "

J'ai besoin de la suppression de la station Stations de la table et des propriétés liées à la table RegulatorySchedules DispatchStation et DestinationStation exposées à NULL . Mais l'option Restrict est une exception lorsque vous supprimez un SetNull que je ne peux pas mettre . Tell me comment être?

7
Aldmi

Le "problème" décrit n’est pas lié à Entity Framework - c’est la restriction de MS SQL Server lui-même. Un tableau avec plusieurs FK peut ne contenir qu'un seul avec cascade delete.

Donc, dès que vous avez besoin que les deux FK aient cascade -, vous devez implémenter un tel "nettoyage" dans votre code. Définissez l'un (ou les deux) FK sur DeleteBehavior.Restrict et dans votre contrôleur/service avant de supprimer Station, recherchez et supprimez manuellement tous les RegulatorySchedule associés.

10
Dmitry

La réponse de Dmitry a parfaitement fonctionné. Pour tous les futurs voyageurs, un échantillon de travail d'un tableau de correspondance ci-dessous.

Le code se trouve dans la méthode OnModelCreating(ModelBuilder modelBuilder) de votre classe DbContext:

modelBuilder.Entity<AB>()
            .HasKey(e => new { e.AId, e.BId});

modelBuilder.Entity<AB>()
            .HasOne(e => e.A)
            .WithMany(e => e.ABs)
            .HasForeignKey(e => e.AId)
            .OnDelete(DeleteBehavior.Cascade); // <= This entity has cascading behaviour on deletion

modelBuilder.Entity<AB>()
            .HasOne(e => e.B)
            .WithMany(e => e.ABs)
            .HasForeignKey(e => e.BId)
            .OnDelete(DeleteBehavior.Restrict); // <= This entity has restricted behaviour on deletion
2
mmr