【发布时间】: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