簡體   English   中英

如何在 EF 代碼優先中禁用鏈接表的級聯刪除?

[英]How to disable cascade delete for link tables in EF code-first?

我想禁用具有實體框架代碼優先的鏈接表的級聯刪除。 例如,如果許多用戶有很多角色,並且我嘗試刪除一個角色,我希望阻止該刪除,除非當前沒有與該角色關聯的用戶。 我已經刪除了OnModelCreating中的級聯刪除約定:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    ...
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

然后我設置了用戶角色鏈接表:

modelBuilder.Entity<User>()
    .HasMany(usr => usr.Roles)
    .WithMany(role => role.Users)
    .Map(m => {
        m.ToTable("UsersRoles");
        m.MapLeftKey("UserId");
        m.MapRightKey("RoleId");
    });

然而,當 EF 創建數據庫時,它會為外鍵關系創建刪除級聯,例如。

ALTER TABLE [dbo].[UsersRoles]  WITH CHECK ADD  CONSTRAINT [FK_dbo.UsersRoles_dbo.User_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([UserId])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[UsersRoles]  WITH CHECK ADD  CONSTRAINT [FK_dbo.UsersRoles_dbo.Role_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[Role] ([RoleId])
ON DELETE CASCADE
GO

如何停止 EF 生成此刪除級聯?

我得到了答案。 :-) 由於ManyToManyCascadeDeleteConvention正在創建這些級聯刪除。 您需要刪除此約定以防止它為鏈接表創建級聯刪除:

modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

我相信在全球范圍內關閉ManyToManyCascadeDeleteConvention不是一個明智的選擇。 相反,最好只為相關表關閉它。

這可以通過編輯生成的遷移文件來實現,對於屬性cascadeDelete 例如:

AddForeignKey("dbo.UsersRoles", "UserId", "dbo.User", "UserId", cascadeDelete: false);

我同意 Ebram Khalil 的觀點,即為單張桌子關閉它是一個不錯的選擇。 但是,我喜歡盡可能接近自動構建的遷移,因此我會在 OnModelCreating 中進行設置:

modelBuilder.Entity<User>()
    .HasMany(usr => usr.Roles)
    .WithMany(role => role.Users)
    .Map(m => {
        m.ToTable("UsersRoles");
        m.MapLeftKey("UserId");
        m.MapRightKey("RoleId");
    })
    .WillCascadeOnDelete(false);

我相信這會保留刪除的另一個方向,因此如果兩者都需要被阻止(在本例中有意義),則需要從Entity<User>(Role)開始進行類似的調用

當然,這是在提出問題后很久才出現的。 所以它可能在 2012 年無效。

根據ms docs ,這適用於我在 EFCore 6.0.1 和 MySql 中。

注意:不要忘記在此之后重新生成遷移文件。

// In your dbContext class
protected override void OnModelCreating(ModelBuilder modelBuilder)
{    
     modelBuilder
          .Entity<User>()
          .HasMany(usr => usr.Roles)
          .WithMany(role => role.Users)
          .OnDelete(DeleteBehavior.Restrict);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM