如何使用cascade delete删除所有租户数据

31moq8wy  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(310)

当删除一个租户时,我想从多租户数据库中删除与租户相关的所有实体。我正在使用efcore和microsoftsqlserver,不过我想这个主题并不局限于这些技术。
在这个回答中,据说:
这是使用带有on cascade选项的外键的典型情况
不过,我还没能成功。似乎由于被租用的实体也在它们之间链接,所以会创建循环。我已经创建了一个简单的应用程序来单独测试,你可以在这里找到它。尝试根据迁移更新数据库时,出现以下错误:
未处理的异常。microsoft.data.sqlclient.sqlexception(0x80131904):在表“posts”上引入外键约束“fk\u posts\u tenantid”可能会导致循环或多个级联路径。指定on delete no action或on update no action,或修改其他外键约束。
我的数据库上下文和实体:

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; }
}

所以我的问题是:这可能吗?如果是的话,我应该改变我的配置什么?我读过,使实体间的fk可以为null可以解决这个问题,但我不想仅仅为了使这个工作而改变。我也看到过用触发器替换级联删除的答案,但是我不喜欢这个选项。

tgabmvqs

tgabmvqs1#

你有“多个级联路径” Post :

Tenant => Blog => Post
Tenant => Post
``` `Post.TenantId` 是多余的,因为帖子包含在特定于租户的 `Blog` .
有多种可能性:
删除post.tenatid
删除租户和帖子之间的引用(替换为blog和post)
添加正确的 `OnDelete()` 行为(ms文档)

相关问题