【问题标题】:How to use CASCADE DELETE for removing all tenant data如何使用 CASCADE DELETE 删除所有租户数据
【发布时间】:2020-11-03 18:56:40
【问题描述】:

当一个租户被删除时,我想从多租户数据库中删除与一个租户相关的所有实体。我正在使用 EF Core 和 Microsoft SQL Server,虽然我猜这个主题不限于这些技术。

this answer中是这样说的:

这是使用带有 ON CASCADE 选项的 FOREIGN KEYS 的经典案例

但是,我还没有成功。似乎由于 tenantized 实体也在它们之间链接,因此会创建循环。我创建了一个简单的应用程序来单独测试它,你可以找到它here。尝试根据迁移更新数据库时,出现以下错误:

未处理的异常。 Microsoft.Data.SqlClient.SqlException (0x80131904):在表 'Posts' 上引入 FOREIGN KEY 约束 'FK_Posts_Tenants_TenantId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

我的 DbContext 和实体:

public class BloggingContext : DbContext
{
    public DbSet<Tenant> Tenants { get; set; }
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlServer("Server=.;Database=TestCascadeDelete;Trusted_Connection=True");
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>(b => b.HasOne<Tenant>().WithMany().HasForeignKey(e => e.TenantId));
        modelBuilder.Entity<Post>(b => b.HasOne<Tenant>().WithMany().HasForeignKey(e => e.TenantId));
    }
}
public class Tenant
{
    public int TenantId { get; set; }
}
public class Blog
{
    public int TenantId { get; set; }
    public int BlogId { get; set; }
    public List<Post> Posts { get; } = new List<Post>();
}
public class Post
{
    public int TenantId { get; set; }
    public int PostId { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

所以我的问题是:这可能吗?如果是,我应该在我的配置中进行哪些更改? 我已经 read 认为使实体之间的 FK 可以为空可以解决问题,但我不想仅仅为了使这项工作正常进行更改.我还看到 this answer 用触发器替换 CASCADE DELETE,但我不喜欢这个选项。

【问题讨论】:

  • 所有表都有TenantId列吗?
  • @PrebenHuybrechts,是的。
  • 您可以尝试this 方法。总结,它根据外键生成一个删除脚本。然后你可以添加WHERE TenantId = X

标签: sql sql-server entity-framework-core cascade


【解决方案1】:

Post 有“多个级联路径”:

Tenant => Blog => Post
Tenant => Post

Post.TenantId 是多余的,因为 Post 包含在特定于租户的 Blog 中。

有多种可能性:

  • 删除 Post.TenantId
  • 删除租户和帖子之间的引用(替换为博客和帖子)
  • 添加正确的OnDelete() 行为 (MS docs)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多