Entity Framework,外键约束可能导致循环或多级联路径
Entity Framework, Foreign key constraint may cause cycles or multiple cascade paths
我的项目首先使用实体代码。基本上我有 3 class Users
,Branchs
和 UsersBranchs
.
Users
包含 UserID
, Name
,...
Branchs
包含 BranchID
, Location
, ... 和 UserID,这是指分支的创建者
UsersBranchs
只有两列 BranchID 和 UserID,它们定义了哪个用户在哪个分支中
问题是我得到这个错误:
'FK_dbo.UsersBranchs_dbo.Users_UsersID' on table 'UsersBranchs' may
cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or
ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
你能帮帮我吗?
更新
这是 UsersBranchs Class
[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 class 以使用 UserID 和 BranchID 作为键
modelBuilder.Entity().HasKey(x => new { x.UserID, x.BranchID });
分支 Class 是
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ID { get; set; }
[ForeignKey("UserID")]
public CoreUsers User { get; set; }
public Guid UserID { get; set; }
public .....
用户 Class 是
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ID { get; set; }
public .....
无法 handle multiple cascade paths and cascade delete to same table 长期以来一直是 Sql 服务器的限制。只是 Google 错误信息。基本上,如果您想使用级联删除,那么您必须确保只有一个级联路径。
目前您有两条路径:Branchs -> UsersBranchs 和 Branchs -> Users -> 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)。见 Entity Framework documentation.
除此之外,您的模型似乎有点奇怪。您看起来像是在尝试创建多对多 link/join table、UsersBranchs,但您在 Branch 上也有一个 User,这实际上没有任何意义。在那种情况下你甚至需要 UsersBranchs table 吗?你的意思是在你的分支上有一个用户集合,即导航 属性 而不是外键,它给出了一对多的关系 Branch -> Users?
顺便说一句,我真的不喜欢对单个实体使用复数形式。
我认为您遇到了问题,因为您没有告诉 Entity framework 它将如何处理这些 class 在级联删除时
在您的 DbContext class 中,覆盖 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);
}
希望这对您有所帮助
我的项目首先使用实体代码。基本上我有 3 class Users
,Branchs
和 UsersBranchs
.
Users
包含 UserID
, Name
,...
Branchs
包含 BranchID
, Location
, ... 和 UserID,这是指分支的创建者
UsersBranchs
只有两列 BranchID 和 UserID,它们定义了哪个用户在哪个分支中
问题是我得到这个错误:
'FK_dbo.UsersBranchs_dbo.Users_UsersID' on table 'UsersBranchs' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
你能帮帮我吗?
更新
这是 UsersBranchs Class
[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 class 以使用 UserID 和 BranchID 作为键
modelBuilder.Entity().HasKey(x => new { x.UserID, x.BranchID });
分支 Class 是
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ID { get; set; }
[ForeignKey("UserID")]
public CoreUsers User { get; set; }
public Guid UserID { get; set; }
public .....
用户 Class 是
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ID { get; set; }
public .....
无法 handle multiple cascade paths and cascade delete to same table 长期以来一直是 Sql 服务器的限制。只是 Google 错误信息。基本上,如果您想使用级联删除,那么您必须确保只有一个级联路径。
目前您有两条路径:Branchs -> UsersBranchs 和 Branchs -> Users -> 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)。见 Entity Framework documentation.
除此之外,您的模型似乎有点奇怪。您看起来像是在尝试创建多对多 link/join table、UsersBranchs,但您在 Branch 上也有一个 User,这实际上没有任何意义。在那种情况下你甚至需要 UsersBranchs table 吗?你的意思是在你的分支上有一个用户集合,即导航 属性 而不是外键,它给出了一对多的关系 Branch -> Users?
顺便说一句,我真的不喜欢对单个实体使用复数形式。
我认为您遇到了问题,因为您没有告诉 Entity framework 它将如何处理这些 class 在级联删除时
在您的 DbContext class 中,覆盖 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);
}
希望这对您有所帮助