实体框架,外键约束可能会导致循环或多个级联路径
本文关键字:循环 路径 级联 框架 约束 实体 | 更新日期: 2023-09-27 18:36:16
我首先在我的项目中使用实体代码。基本上我有3个班级Users
,Branchs
和UsersBranchs
。
Users
包含UserID
、Name
,...
Branchs
包含BranchID
、Location
、... 和用户ID,指的是分支的创建者UsersBranchs
只有两列分支ID和用户ID,用于定义哪个用户在哪个分支中
问题是我收到此错误:
"FK_dbo。UsersBranchs_dbo。表"用户分支"上的Users_UsersID"可以 导致周期或多个级联路径。指定"删除时不执行任何操作"或 在更新时不执行任何操作,或修改其他外键约束。
你能帮我吗?
更新
它是用户分支类
[ForeignKey("UserID")]
public CoreUsers User { get; set; }
public Guid UsersID { get; set; }
[ForeignKey("BranchID")]
public Branchs Branch { get; set; }
public Guid BranchID { get; set; }
并将此行添加到 DbContext 类中,以同时使用 UserID 和 BranchID 作为键
modelBuilder.Entity().HasKey(x => new { x.UserID, x.BranchID });
分支类是
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ID { get; set; }
[ForeignKey("UserID")]
public CoreUsers User { get; set; }
public Guid UserID { get; set; }
public .....
用户类为
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ID { get; set; }
public .....
无法处理多个级联路径和级联删除到同一个表一直是 Sql Server 的限制。只需谷歌错误消息。基本上,如果要使用级联删除,则必须确保只有一个级联路径。
目前,您有两条路径来自分支 -> UsersBranchs 和分支 -> 用户 -> UsersBranchs。
默认情况下,EF 设置级联删除,但可以通过删除 DbContext 中的约定来停止。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Manually set cascade delete behaviour
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
然后,您必须在您想要级联删除的任何关系上设置 WillCascadeOnDelete(true)。请参阅实体框架文档。
除此之外,您的模型似乎有点奇怪。您看起来像是在尝试制作一个多对多链接/连接表,UsersBranchs,但是您在分支上也只有一个用户,这实际上没有意义。在这种情况下,您甚至需要 UsersBranchs 表吗?您的意思是在您的分支上有一个用户集合,即导航属性而不是外键,它提供了一对多关系分支 ->用户?
顺便说一句,我真的很不喜欢对单个实体使用复数形式。
我认为您遇到了问题,因为您没有告诉实体框架它将如何在级联删除时处理这些类
在 DbContext 类中,重写 OnModelCreating 方法并编写此代码
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserBranch>()
.HasRequired(t => t.CoreUsers)
.WithMany()
.HasForeignKey(t => t.UserID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<UserBranch>()
.HasRequired(t => t.Branch)
.WithMany()
.HasForeignKey(t => t.BranchID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Branch>()
.HasRequired(t => t.User)
.WithMany()
.HasForeignKey(t => t.UserID)
.WillCascadeOnDelete(false);
}
希望这对你有帮助