Specificare ON DELETE NO ACTION in Entity Framework 7?

entity-framework-core

Domanda

In Entity Framework 7 quando sto provando ad applicare una migrazione ottengo l'errore

L'introduzione del vincolo FOREIGN KEY "FK_ChangeOrder_User_CreatedByID" nella tabella "ChangeOrder" può causare cicli o più percorsi a cascata. Specificare ON DELETE NO ACTION o ON UPDATE NO ACTION o modificare altri vincoli FOREIGN KEY.
Impossibile creare un vincolo. Vedi errori precedenti.

So che nelle versioni precedenti di Entity Framework ci si sarebbe occupati di ciò aggiungendo

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

al DbContext ma in EF7 modelBuilder non sembra avere una .Conventions e google restituisce solo i risultati precedenti di EF 4 anche se EF 6.

Come si specifica il vincolo ON DELETE NO ACTION in Entity Framework 7?

Modifica: La risposta fornita da Oleg apparentemente lo farà per chiave esterna, ma mi piacerebbe farlo globalmente poiché sarà molto più semplice usare una riga di codice per dichiararla globalmente, quindi devi specificare il codice per ogni singolo centinaia di relazioni finirò per avere.

Modifica 2: codice per Oleg

public class ChangeOrder
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public Int16? ApprovedByID { get; set; }
    public Byte ApprovalStatusID { get; set; }
    public Int16 AssignedToID { get; set; }
    public Int16 CreatedByID { get; set; }
    public Byte CurrentStatusID { get; set; }
    public DateTime? DateApproved { get; set; }
    public DateTime? EndDate { get; set; }
    public Byte ImpactID { get; set; }
    public Byte PriorityID { get; set; }
    public DateTime? StartDate { get; set; }
    public Byte TypeID { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string ReasonForChange { get; set; }

    [ForeignKey("ApprovedByID")]
    public User ApprovedBy { get; set; }

    [ForeignKey("ApprovalStatusID")]
    public ChangeApprovalStatus ApprovalStatus { get; set; }

    [ForeignKey("AssignedToID")]
    public User AssignedTo { get; set; }

    [ForeignKey("CreatedByID")]
    public User CreatedBy { get; set; }

    [ForeignKey("ImpactID")]
    public ChangeImpact Impact { get; set; }

    [ForeignKey("PriorityID")]
    public ChangePriority Priority { get; set; }

    [ForeignKey("TypeID")]
    public ChangeType ChangeType { get; set; }

    [ForeignKey("CurrentStatusID")]
    public ChangeStatus CurrentStatus { get; set; }
}
public class JobSightDBContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        base.OnModelCreating(modelbuilder);
    }

    DbSet<ChangeApprovalStatus> ChangeApprovalStatus { get; set; }
    DbSet<ChangeImpact> ChangeImapct { get; set; }
    DbSet<ChangeOrder> ChangeOrders { get; set; }
    DbSet<ChangePriority> ChangePriorities { get; set; }
    DbSet<ChangeStatus> ChangeStatus { get; set; }
    DbSet<ChangeType> ChangeTypes { get; set; }
    DbSet<User> Users { get; set; }
}

Risposta accettata

Dopo aver esplorato GitHub e aver lavorato con un ragazzo molto esperto di MS, la soluzione attuale è aggiungerla al DbContext

protected override void OnModelCreating(ModelBuilder modelbuilder)
{
    foreach (var relationship in modelbuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
    {
        relationship.DeleteBehavior = DeleteBehavior.Restrict;
    }

    base.OnModelCreating(modelbuilder);
}

Risposta popolare

La costruzione

modelBuilder.Entity("myNamespace.Models.ChangeOrder", b =>
    {
        b.HasOne("myNamespace.Models.User")
            .WithMany()
            .HasForeignKey("CreatedByID")
            .OnDelete(DeleteBehavior.Cascade);
    });

significherà creare FK_ChangeOrder_User_CreatedByID con REFERENCES [dbo].[User] ([CreatedByID]) ON DELETE CASCADE . Dovrebbe esistere in protected override void BuildModel(ModelBuilder modelBuilder) di YourContextModelSnapshot.cs creato durante la migrazione. Non sono sicuro di comprendere appieno la tua domanda, ma penso che dovresti aggiungere tale costrutto a XXXModelSnapshot.cs o rimuovere il costrutto non necessario, che esiste già qui.

AGGIORNATO: vedo che hai il problema nel modello. Hai le seguenti proprietà in

public Int16? ApprovedByID { get; set; }
public Int16 AssignedToID { get; set; }
public Int16 CreatedByID { get; set; }

// navigation properties

[ForeignKey("ApprovedByID")]
public User ApprovedBy { get; set; }

[ForeignKey("AssignedToID")]
public User AssignedTo { get; set; }

[ForeignKey("CreatedByID")]
public User CreatedBy { get; set; }

Per impostazione predefinita, prova a impostare DeleteBehavior.Cascade su tutte le proprietà.

È possibile sovrascrivere il comportamento modificando OnModelCreating , che imposta il comportamento DeleteBehavior.Restrict per tutte le chiavi o imposta su una sola chiave il comportamento DeleteBehavior.Cascade o DeleteBehavior.SetNull . Ad esempio, il codice seguente utilizza DeleteBehavior.Cascade su CreatedByID (che crea ON DELETE CASCADE sulle chiavi esterne) e DeleteBehavior.Restrict su altre chiavi esterne (no ON DELETE sulle chiavi esterne):

public class JobSightDBContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        base.OnModelCreating(modelbuilder);

        modelbuilder.Entity(typeof (ChangeOrder))
            .HasOne(typeof (User), "ApprovedBy")
            .WithMany()
            .HasForeignKey("ApprovedByID")
            .OnDelete(DeleteBehavior.Restrict); // no ON DELETE
        modelbuilder.Entity(typeof (ChangeOrder))
            .HasOne(typeof (User), "AssignedTo")
            .WithMany()
            .HasForeignKey("AssignedToID")
            .OnDelete(DeleteBehavior.Restrict); // no ON DELETE
        modelbuilder.Entity(typeof (ChangeOrder))
            .HasOne(typeof (User), "CreatedBy")
            .WithMany()
            .HasForeignKey("CreatedByID")
            .OnDelete(DeleteBehavior.Cascade); // set ON DELETE CASCADE
    }

    DbSet<ChangeApprovalStatus> ChangeApprovalStatus { get; set; }
    DbSet<ChangeImpact> ChangeImapct { get; set; }
    DbSet<ChangeOrder> ChangeOrders { get; set; }
    DbSet<ChangePriority> ChangePriorities { get; set; }
    DbSet<ChangeStatus> ChangeStatus { get; set; }
    DbSet<ChangeType> ChangeTypes { get; set; }
    DbSet<User> Users { get; set; }
}


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché