一对多 - FOREIGN KEY 约束可能导致循环或多个级联路径
One to Many - FOREIGN KEY constraint may cause cycles or multiple cascade paths
我有一个 class Dienstbulletin,其中包含同一 class 人物的多个属性。
当我执行更新数据库命令时。我收到以下错误:
在 table 'Dienstbulletin' 上引入 FOREIGN KEY 约束 'FK_dbo.Dienstbulletin_dbo.Persoon_OgpID' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
无法创建约束或索引。查看以前的错误。
public class Persoon : DefaultFields
{
[Required]
[StringLength(50, ErrorMessage = "Naam mag niet langer zijn dan 50 karakters.")]
public string Naam { get; set; }
[Display(Name = "Type")]
[Range(1, int.MaxValue, ErrorMessage = "Selecteer een correct type")]
[Required]
public TypePersoon TypePersoon { get; set; }
[Required]
public Boolean Actief { get; set; }
[InverseProperty("Ogp")]
public ICollection<Dienstbulletin> OgpCollection { get; set; }
[InverseProperty("Obp")]
public ICollection<Dienstbulletin> ObpCollection { get; set; }
[InverseProperty("Rechercheur")]
public ICollection<Dienstbulletin> RechercheurCollection { get; set; }
[InverseProperty("Opsteller")]
public ICollection<Dienstbulletin> OpstellerCollection { get; set; }
}
public class Dienstbulletin : DefaultFields
{
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public string Datum { get; set; }
[Display(Name = "Ploeg")]
[Required]
public int PloegID { get; set; }
public virtual Gebruiker Ploeg { get; set; }
public int VoertuigID { get; set; }
public virtual Voertuig Voertuig { get; set; }
[Display(Name = "Opsteller")]
[Required]
[ForeignKey("Opsteller")]
public int OpstellerID { get; set; }
public Persoon Opsteller { get; set; }
[Display(Name = "OGP met dienst")]
[Required]
[ForeignKey("Ogp")]
public int OgpID { get; set; }
public Persoon Ogp { get; set; }
[Display(Name = "OBP met dienst")]
[Required]
[ForeignKey("Obp")]
public int ObpID { get; set; }
public Persoon Obp { get; set; }
[Display(Name = "Rechercheur met dienst")]
[Required]
[ForeignKey("Rechercheur")]
public int RechercheurID { get; set; }
public Persoon Rechercheur { get; set; }
[Column(TypeName = "varchar(MAX)")]
[Display(Name = "Aandachtsvestigingen")]
public string Aandachtspunten { get; set; }
[Column(TypeName = "varchar(MAX)")]
[Display(Name = "Bijkomende opdrachten")]
public string BijkomendeOpdrachten { get; set; }
#region Collections
public virtual ICollection<Opdracht> OpdrachtCollection { get; set; }
#endregion
}
public class DienstbulletinAppContext : DbContext
{
public DienstbulletinAppContext() : base("Dienstbulletin"){}
public DbSet<Dienstbulletin> Dienstbulletin { get; set; }
public DbSet<Voertuig> Voertuigen { get; set; }
public DbSet<Opdracht> Opdrachts { get; set; }
public DbSet<OpdrachtDetail> OpdrachtDetails { get; set; }
public DbSet<Locatie> Locaties { get; set; }
public DbSet<Gebruiker> Gebruikers { get; set; }
public DbSet<Persoon> Personen { get; set; }
public DbSet<OpdrachtType> OpdrachtTypes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Obp)
.WithMany()
.HasForeignKey(u => u.ObpID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Ogp)
.WithMany()
.HasForeignKey(u => u.OgpID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Rechercheur)
.WithMany()
.HasForeignKey(u => u.RechercheurID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Opsteller)
.WithMany()
.HasForeignKey(u => u.OpstellerID)
.WillCascadeOnDelete(false);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
谁能解释我做错了什么以及我该如何解决这个问题?
这是一个示例,说明如何使用 Fluent API 关闭关系的级联删除。只需将 Type1
和 Type2
替换为正确的类型即可。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Type1>()
.HasOne(i => i.Type2)
.WithMany(c => c.Type1s)
.OnDelete(DeleteBehavior.SetNull);
}
对我来说,解决方案是这样的:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
我有一个 class Dienstbulletin,其中包含同一 class 人物的多个属性。 当我执行更新数据库命令时。我收到以下错误:
在 table 'Dienstbulletin' 上引入 FOREIGN KEY 约束 'FK_dbo.Dienstbulletin_dbo.Persoon_OgpID' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。
public class Persoon : DefaultFields
{
[Required]
[StringLength(50, ErrorMessage = "Naam mag niet langer zijn dan 50 karakters.")]
public string Naam { get; set; }
[Display(Name = "Type")]
[Range(1, int.MaxValue, ErrorMessage = "Selecteer een correct type")]
[Required]
public TypePersoon TypePersoon { get; set; }
[Required]
public Boolean Actief { get; set; }
[InverseProperty("Ogp")]
public ICollection<Dienstbulletin> OgpCollection { get; set; }
[InverseProperty("Obp")]
public ICollection<Dienstbulletin> ObpCollection { get; set; }
[InverseProperty("Rechercheur")]
public ICollection<Dienstbulletin> RechercheurCollection { get; set; }
[InverseProperty("Opsteller")]
public ICollection<Dienstbulletin> OpstellerCollection { get; set; }
}
public class Dienstbulletin : DefaultFields
{
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public string Datum { get; set; }
[Display(Name = "Ploeg")]
[Required]
public int PloegID { get; set; }
public virtual Gebruiker Ploeg { get; set; }
public int VoertuigID { get; set; }
public virtual Voertuig Voertuig { get; set; }
[Display(Name = "Opsteller")]
[Required]
[ForeignKey("Opsteller")]
public int OpstellerID { get; set; }
public Persoon Opsteller { get; set; }
[Display(Name = "OGP met dienst")]
[Required]
[ForeignKey("Ogp")]
public int OgpID { get; set; }
public Persoon Ogp { get; set; }
[Display(Name = "OBP met dienst")]
[Required]
[ForeignKey("Obp")]
public int ObpID { get; set; }
public Persoon Obp { get; set; }
[Display(Name = "Rechercheur met dienst")]
[Required]
[ForeignKey("Rechercheur")]
public int RechercheurID { get; set; }
public Persoon Rechercheur { get; set; }
[Column(TypeName = "varchar(MAX)")]
[Display(Name = "Aandachtsvestigingen")]
public string Aandachtspunten { get; set; }
[Column(TypeName = "varchar(MAX)")]
[Display(Name = "Bijkomende opdrachten")]
public string BijkomendeOpdrachten { get; set; }
#region Collections
public virtual ICollection<Opdracht> OpdrachtCollection { get; set; }
#endregion
}
public class DienstbulletinAppContext : DbContext
{
public DienstbulletinAppContext() : base("Dienstbulletin"){}
public DbSet<Dienstbulletin> Dienstbulletin { get; set; }
public DbSet<Voertuig> Voertuigen { get; set; }
public DbSet<Opdracht> Opdrachts { get; set; }
public DbSet<OpdrachtDetail> OpdrachtDetails { get; set; }
public DbSet<Locatie> Locaties { get; set; }
public DbSet<Gebruiker> Gebruikers { get; set; }
public DbSet<Persoon> Personen { get; set; }
public DbSet<OpdrachtType> OpdrachtTypes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Obp)
.WithMany()
.HasForeignKey(u => u.ObpID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Ogp)
.WithMany()
.HasForeignKey(u => u.OgpID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Rechercheur)
.WithMany()
.HasForeignKey(u => u.RechercheurID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Dienstbulletin>()
.HasRequired(c => c.Opsteller)
.WithMany()
.HasForeignKey(u => u.OpstellerID)
.WillCascadeOnDelete(false);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
谁能解释我做错了什么以及我该如何解决这个问题?
这是一个示例,说明如何使用 Fluent API 关闭关系的级联删除。只需将 Type1
和 Type2
替换为正确的类型即可。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Type1>()
.HasOne(i => i.Type2)
.WithMany(c => c.Type1s)
.OnDelete(DeleteBehavior.SetNull);
}
对我来说,解决方案是这样的:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}