我的MVC项目中有以下内容(代码优先方法) 我想知道我收到以下错误的原因是什么
引入FOREIGN KEY约束 表'VendorDetails'上的'FK_dbo.VendorDetails_dbo.States_StateID'可以 导致循环或多个级联路径。指定ON DELETE NO ACTION或 ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。可以 不创造约束。查看以前的错误。
我只是想知道哪些表获得了多个级联路径,任何图表都是有效的,我应该使用流畅的API编写这样的代码:
modelBuilder.Entity<...>() .HasRequired(...) .WithMany(...) .HasForeignKey(...) .WillCascadeOnDelete(false);
public class VendorDetails
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int VendorID { get; set; }
[MaxLength(60)]
public string VendorName { get; set; }
public int VendorTypeID { get; set; }
public int CountryID { get; set; }
public int StateID { get; set; }
[NotMapped]
public string CountryName { get; set; }
[NotMapped]
public string StateName { get; set; }
[NotMapped]
public string VendorTypeName { get; set; }
public virtual Country Country { get; set; }
public virtual State State { get; set; }
public virtual VendorType VendorType { get; set; }
}
public class VendorType
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int VendorTypeID { get; set; }
public string VendorTypeName { get; set; }
public virtual ICollection<VendorDetails> Vendors { get; set; }
}
public class Country
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CountryID { get; set; }
public string CountryName { get; set; }
public virtual ICollection<State> States { get; set; }
}
public class State
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int StateID { get; set; }
public string StateName { get; set; }
public int CountryID { get; set; }
public virtual Country Country { get; set; }
}
答案 0 :(得分:2)
你得到的是因为Country有一个指向State的链接,VendorDetails有一个指向Country和State的链接。这给出了VendorDetails和State之间的多条路径 - 一个通过Country,一个直接。
我会在VendorDetails的链接上禁用级联删除:
modelBuilder
.Entity<VendorDetails>()
.HasOptional(e => e.State)
.WithMany()
.WillCascadeOnDelete(false);
答案 1 :(得分:0)
替代@ Richard的建议,在创建迁移时,它可能具有“删除”功能。在约束部分中指定。
即
table.ForeignKey( name: "FK_ServiceRequest_User_DeletedById",
column: x => x.DeletedById,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
您可以简单地删除本节的最后一行(假设您的默认设置是不执行任何操作)。否则,将onDelete
设置为ReferentialAction.NoAction
具有相同的结果。
我个人更喜欢@ Richard的做法,因为它将后期处理放在一个地方(上下文),这意味着当你在寻找这样的事情时,你不是这样的。必须搜索可能是大量迁移的内容,但这是一种可以使迁移保持自我管理的替代方案。