引入 FOREIGN KEY 约束可能会导致循环或多重级联路径 - 如何指定 ON DELETE NO ACTION?

问题描述 投票:0回答:1

我总共有 6 个实体,但我的问题是以下 3 个, “部门”“Filier”“Etudiant” 实体,

'Departement' 实体包含许多 'Filiere' 和许多 'Etudiant' 实体,而 'Filiere''Etudiant' 仅与 1 个 'Departement' 实体关联。

这是我添加迁移并第一次尝试更新数据库后的错误消息:

在表“Etudiant”上引入外键约束“FK_Etudiant_Filiere_FiliereId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看之前的错误。

这是我的“部门”实体:

using System.ComponentModel.DataAnnotations;

namespace Scolarité.Models
{
    public class Departement
    {

        public int Id { get; set; }


        [Required(ErrorMessage = "Libellé Obligatoire")]
        [StringLength(100, MinimumLength = 3)]
        [Display(Name = "Departement")]
        public string LibelleD { get; set; }

        [Required(ErrorMessage = "Chef Departement Obligatoire")]
        [StringLength(30, MinimumLength = 3)]
        [Display(Name = " Chef Departement")]
        public string ChefD { get; set; }

        public virtual ICollection<Filiere> Filieres { get; set; }
        public virtual ICollection<Semestre> Semestre { get; set; }
        public virtual ICollection<Unite> Unite { get; set; }
        public virtual ICollection<Etudiant> Etudiant { get; set; }
    }
}

这是我的 'Filiere' 实体:

using System.ComponentModel.DataAnnotations;

namespace Scolarité.Models
{
    public class Filiere
    {
        public int Id { get; set; }


        [Required(ErrorMessage = "Libellé filiére Obligatoire")]
        [StringLength(100, MinimumLength = 3)]
        [Display(Name = " Libelle Filiére")]
        public string LibelleF { get; set; }

        public int DepartementId { get; set; }
        public virtual Departement Departement { get; set; }
    
        public virtual ICollection<Etudiant> Etudiants { get; set; }
        public virtual ICollection<Unite> Unite { get; set; }
        public virtual ICollection<Semestre> Semestre { get; set; }
    }
}

这是我的“学生”实体:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Scolarité.Models
{
    public class Etudiant
    {
        public int Id { get; set; }


        [Required(ErrorMessage = "Nom Obligatoire")]
        [StringLength(30, MinimumLength = 3)]
        public string Nom { get; set; }

        [Required(ErrorMessage = "Prenom Obligatoire")]
        [StringLength(30, MinimumLength = 3)]
        public string Prenom { get; set; }

        

        [Required(ErrorMessage = "CIN Obligatoire")]
        [RegularExpression(@"^\d{8}$", ErrorMessage = "Le CIN doit comporter 8 chiffres.")]
        public string Cin { get; set; }

        [Required(ErrorMessage = "Mot de passe Obligatoire")]
        [DataType(DataType.Password)]
        public string Password { get; set; }





        [Display(Name = " Departement")]
        public int DepartementId { get; set; }
        public virtual Departement Departement { get; set; }



        [Display(Name = " Filiére")]
        public int FiliereId { get; set; }
        public virtual Filiere Filiere { get; set; }
    }
}

我在 stackoverflow 上查看了与我的问题相关的 YouTube 视频和其他帖子,并尝试了他们的解决方案,但它们对我不起作用,尽管我相信我很可能错误地实现了它们,这就是我现在在这里的原因。

1-我尝试使外键可为空,即使它们不适合我的情况,但这并没有解决问题

2-我尝试通过转到我的 dbcontext 并将以下代码添加到“OnModelCreating(ModelBuilder modelBuilder)”方法中,将 onDelete 选项更改为 NoActionClientSetNull,但它仍然给出相同的错误消息,就像虽然我没有改变任何事情:

我的

DbContextOnModelCreating 方法:

using Microsoft.EntityFrameworkCore;
using Scolarité.Models;

public class ScolaritéContext : DbContext
{
    public ScolaritéContext(DbContextOptions<ScolaritéContext> options)
        : base(options)
    {
    }

    public DbSet<Departement> Departement { get; set; } = default!;
    public DbSet<EE> EE { get; set; } = default!;
    public DbSet<Etudiant> Etudiant { get; set; } = default!;
    public DbSet<Filiere> Filiere { get; set; } = default!;
    public DbSet<Semestre> Semestre { get; set; } = default!;
    public DbSet<Unite> Unite { get; set; } = default!;


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);



        modelBuilder.Entity<Departement>()
                .HasMany(d => d.Filieres)
                .WithOne(f => f.Departement)
                .HasForeignKey(f => f.DepartementId)
                .OnDelete(DeleteBehavior.NoAction);


        
        modelBuilder.Entity<Filiere>()
           .HasMany(f => f.Etudiants)
           .WithOne(e => e.Filiere)
           .HasForeignKey(e => e.FiliereId)
           .OnDelete(DeleteBehavior.NoAction); 


        modelBuilder.Entity<Etudiant>()
                .HasOne(e => e.Departement)
                .WithMany(d => d.Etudiant)
                .HasForeignKey(e => e.DepartementId)
                .OnDelete(DeleteBehavior.NoAction);


        modelBuilder.Entity<Etudiant>()
                .HasOne(e => e.Filiere)
                .WithMany(f => f.Etudiants)
                .HasForeignKey(e => e.FiliereId)
                .OnDelete(DeleteBehavior.NoAction);




    }

}

asp.net asp.net-mvc entity-framework foreign-keys ef-code-first
1个回答
0
投票

不使用

.OnDelete(DeleteBehavior.NoAction);
,将以下代码添加到模型构建器解决了我的问题:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
    if (modelBuilder == null)
        throw new ArgumentNullException("modelBuilder");

    // for the other conventions, we do a metadata model loop
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        // equivalent of modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        entityType.SetTableName(entityType.DisplayName());

        // equivalent of modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        entityType.GetForeignKeys()
            .Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade)
            .ToList()
            .ForEach(fk => fk.DeleteBehavior = DeleteBehavior.Restrict);
    }

    base.OnModelCreating(modelBuilder);
...
}
© www.soinside.com 2019 - 2024. All rights reserved.