实体框架(核心) - 级联删除

J. *_*Lee 8 c# entity-framework entity-framework-core

我使用的是 EF Core 3.1.1,但我相信这个问题适用于所有版本的 EF。

EF 似乎具有级联删除的能力 - 如果它已启用,并且依赖对象是否已在上下文中加载。

var blog = context.blogs.Include(x => x.Posts).First(x => x.BlogId == id);
context.blogs.Remove(blog);
Run Code Online (Sandbox Code Playgroud)

上面的语句删除了所有博客的帖子,然后是博客——每个都有不同的 sql 语句。

这就是我想要的,但是在使用代码优先时,它还创建了在数据库中启用级联删除的表。( ON DELETE CASCADE)

是否可以在 EF 中启用级联删除,并依赖 EF 删除依赖对象,而不启用数据库级级联删除?(还是我理解错误?)

原因是迁移失败,因为 SQL 不会在数据库中启用级联删除,因为它检测到多个级联路径(即使多个不会在架构中自然发生)

谢谢!

Iva*_*oev 8

实际上,EF Core 3.0 是 EF 的第一个版本,它通过DeleteBehavior.ClientCascade选项添加了此类功能(遗憾的是尚未包含在文档的级联删除部分):

对于 跟踪的DbContext实体,删除相关主体时将删除依赖实体。

如果数据库是使用 Entity Framework Migrations 或EnsureCreated()方法从模型创建的,那么如果违反外键约束,数据库中的行为将生成错误。

很快,所有的Client*删除行为都被映射到Restrict,即在没有级联的情况下在数据库中强制执行 FK 关系。客户端行为仅适用于上下文跟踪的实体,因此Include在删除之前确保相关数据(如您的示例中所示)。

要配置该选项,您至少需要具有有效Has+ 的流畅 APIWith才能使用OnDelete方法,例如

modelBuilder.Entity<Blog>()
    .HasMany(e => e.Posts)
    .WithOne(e => e.Blog)
    .OnDelete(DeleteBehavior.ClientCascade); 
Run Code Online (Sandbox Code Playgroud)

  • 谢谢伊万 - 这正是我正在寻找的! (2认同)
  • @yogihosting 它有效。仔细阅读答案和文档链接。在您的情况下,级联删除是从国家到城市,而不是您认为的反之亦然。 (2认同)

Erd*_*gan 5

您可以将级联行为添加到您的实体,如下所示。在 OnModelCreating 内;

foreach (var foreignKey in builder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
            {
                foreignKey.DeleteBehavior = DeleteBehavior.Cascade;
            }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述