MVC 4实体框架同一表的两个外键导致循环或多个级联路径
本文关键字:循环 路径 级联 两个 框架 实体 MVC | 更新日期: 2023-09-27 17:59:45
我有两个实体Unit
和UnitPerUnit
。他们的角色是:
Unit
:定义千克、米、厘米、码等单位UnitPerUnit
:保持单位之间的值(例如:1kg=1000gr)
这是代码:
[Table("EA_Unit", Schema = "EAccounting")]
public class EA_Unit
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Display(Name = "Unit Id")]
public int UnitId { get; set; }
[Display(Name = "Unit Name")]
[Index("UnitName", IsUnique = true)]
[MaxLength(20)]
[Required]
public string UnitName { get; set; } //Example kg, piece, roll, yard, meter
public EA_Unit()
{
UnitName = "";
}
}
[Table("EA_UnitPerUnit", Schema = "EAccounting")]
public class EA_UnitPerUnit
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Display(Name = "Unit Per Unit Id")]
public int UnitPerUnitId { get; set; }
[Display(Name = "From Unit")]
[Required]
[Index("UnitToUnit", 1, IsUnique = true)]
public int UnitId { get; set; }
[Display(Name = "To Name")]
[Required]
[Index("UnitToUnit", 2, IsUnique = true)]
public int UnitToUnit { get; set; } //The comparer unit
[Display(Name = "Amount")]
[Required]
public float UnitAmount { get; set; } //how much is this unit to another unit (ex: 1kg = 1000gr)
[ForeignKey("UnitId")]
public virtual EA_Unit Unit { get; set; }
[ForeignKey("UnitToUnit")]
public virtual EA_Unit UnitTo { get; set; }
public EA_UnitPerUnit()
{
UnitId = 0;
UnitToUnit = 0;
UnitAmount = 0;
}
}
每当我运行程序并创建数据库时,都会出现以下错误:
在表"EA_UnitPerUnit"上引入FOREIGN KEY约束"FK_EAccounting.EA_UnitPerUnit_EAccounting.EA_Unit_UnitToUnit"可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。无法创建约束。请参阅以前的错误。
我想要的是,如果删除了Unit
,那么在public virtual EA_Unit Unit { get; set; }
或public virtual EA_Unit UnitTo { get; set; }
中保存该已删除Unit
值的UnitPerUnit
条目也将被删除。
我该如何克服这个问题?我想这样设置数据库,在删除Unit
条目后,数据库将自动删除UnitPerUnit
条目。
这个问题已经一次又一次地得到解决。请参考这个答案。
具有级联删除的外键意味着如果父级中的记录表被删除,则子表中的相应记录将自动删除。这在SQL中被称为级联删除服务器
参考链接。
您需要使用模型生成器来解决此问题。
modelBuilder.Entity<...>()
.HasRequired(...)
.WithMany(...)
.HasForeignKey(...)
.WillCascadeOnDelete(false);
或
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();