'Introducing FOREIGN KEY constraint' 由于级联删除

'Introducing FOREIGN KEY constraint' due to cascading deletes

Introducing FOREIGN KEY constraint 'FK_dbo.CurrentAnimal_dbo.AnimalClass_SelectedAnimalClass' on table 'CurrentAnimal' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

我已经调查了这个问题并从下面的问题中发现了大部分内容。

Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why?

但是我无法从中找到解决方案,因为我的实体关系与提问者截然不同。

假设我的网站用于浏览动物园中的许多不同动物,您通过首先选择 AnimalClass(比如鸟),然后选择 Species(可能是鹰),最后选择所有动物中的特定动物来过滤您的搜索动物园里的老鹰(我们称他为老鹰杰克)。

为了做到这一点,我有 3 个模型 (AnimalClass < Species < Animal),每个模型与其下方的实体都是一对多关系,然后我还有 1 个模型 (CurrentAnimal),每个模型都有 1 个3 个模型,用于管理目的以跟踪哪个特定

AnimalClass < Species < Animal

用户要求查看。

AnimalClass.cs

  public class AnimalClass
  {
    public int Id { get; set; }

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

    //Navigation property
    public virtual ICollection<Species> Species { get; set; }
  }

Species.cs

  public class Species
  {
    public int Id { get; set; }

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

    [Required]
    public int SpeciesAnimalClassId { get; set; }//Foreign Key to the parent Animal Class

    [ForeignKey("SpeciesAnimalClassId")]
    public virtual AnimalClass SpeciesAnimalClass { get; set; }

    //Navigation property
    public virtual ICollection<Animal> Animals { get; set; }
  }

Animal.cs

  public class Animal
  {
    public int Id { get; set; }

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

    [Required]
    public int AnimalsSpeciesId { get; set; }//Foreign Key to the parent Animal Species

    [ForeignKey("AnimalsSpeciesId")]
    public virtual Species AnimalsSpecies { get; set; }
  }

当前Animal.cs

  public class CurrentAnimal
  {
    [Key, ForeignKey("User")]//Acts as both the key to the table, and foreign key to users
    public string UserId { get; set; }

    [Required]
    public int SelectedAnimalClass { get; set; }

    [Required]
    public int SelectedSpecies { get; set; }

    [Required]
    public int SelectedAnimal { get; set; }

    [ForeignKey("SelectedAnimalClass")]
    public virtual AnimalClass AnimalClass { get; set; }

    [ForeignKey("SelectedSpecies")]
    public virtual Species Species { get; set; }

    [ForeignKey("SelectedAnimal")]
    public virtual Animal Animal { get; set; }

    public virtual ApplicationUser User { get; set; }
  }

我知道问题是我有多个级联删除导致异常,我根本无法弄清楚需要删除哪些 Required 注释或我需要使用 Fluent 禁用级联删除的实体 API.

我尝试删除 CurrentAnimal.cs 中的 Required Annotations,然后在我的 DbContext 中使用 Fluent API 来禁用对 AnimalClass、Species 和 Animal 的级联删除,但这并没有改变或删除错误。

这是我在删除 CurrentAnimal.cs

中的 Required 标签后尝试的
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<CurrentAnimal>()
      .HasRequired(s => s.AnimalClass)
      .WithMany()
      .WillCascadeOnDelete(false);

  modelBuilder.Entity<CurrentAnimal>()
      .HasRequired(s => s.Species)
      .WithMany()
      .WillCascadeOnDelete(false);

  modelBuilder.Entity<CurrentAnimal>()
      .HasRequired(s => s.Animal)
      .WithMany()
      .WillCascadeOnDelete(false);

}

多级联路径是因为当一个Species被删除时,有两个路径可能导致CurrentAnimal被删除:

Species -> Animal -> CurrentAnimal
Species -> CurrentAnimal

AnimalClass 也是如此。

如果你绝对必须有这些冗余引用,你需要让它们中的一些成为没有级联的外键。理论上应该还是一样的。

然而,更好的解决方案是不要有无关的引用,因为这会导致数据不一致。例如,您可以拥有一个 CurrentAnimal,其 SelectedSpecies 与 SelectedAnimal 的物种不同。