首页 文章

如何在EF代码优先禁用链接表的级联删除?

提问于
浏览
60

我想禁用具有实体框架代码优先的链接表的级联删除 . 例如,如果许多用户拥有多个角色,并且我尝试删除角色,我希望阻止删除,除非当前没有与该角色关联的用户 . 我已经删除了_2799774中的级联删除约定:

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生成此删除级联?

3 回答

  • 3

    我得到了答案 . :-)由于 ManyToManyCascadeDeleteConvention ,正在创建那些级联删除 . 您需要删除此约定以防止它为链接表创建级联删除:

    modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    
  • 98

    我同意埃布拉姆·哈利勒(Ebram Khalil)的说法,将它关掉一张 table 是一个不错的选择 . 我喜欢尽可能贴近自动构建的迁移,但是,我会在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年没有效 .

  • 4

    我认为全球关闭 ManyToManyCascadeDeleteConvention 并不是明智的选择 . 相反,最好只关闭相关表格 .

    这可以通过编辑生成的迁移文件来实现,属性为 cascadeDelete . 例如:

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

相关问题