强制 ASP.NET 核心实体框架核心中的继承类到专用 MySQL 表



有一个模型Thread,它应该计算另一个模型的所有属性,称为Post我使用继承:

class Post {
public int Id{get;set;}
public string Title{get;set;}
// ...
}
class Thread: Post {
public int ForumId{get;set;}
// ...
}

EF Core 将两者放在一个表中,并将列Discriminator.它包含类的名称,以便 .NET Core 可以将其序列化为正确的类型。

我的目标是:

  • 包含Post模型中所有属性的表Post
  • 包含模型ThreadPost的所有属性的表Thread

为什么?

  1. 我假设这两个表将来都会大幅增长
  2. 它炸毁了我的数据库,因为表定义包含来自Thread行的行,这些行在Post行上总是空
  3. 从开发人员的角度来看,它看起来并不干净和正确

我已经尝试过的

  • 在我的DbContext中创建两个不同的DbSet<T>,用于PostThread
  • 为每个
  • 实体添加builder.Entity<Post>().ToTable("Post")OnModelCreating
  • 在类定义上使用[Table("Post")]装饰器
  • 将共享属性移动到抽象的 chass 中,并让PostThread从中继承

某种解决方法

最后一个有效:

class Content {
// Shared Attributes like Title
}
class Post: Content {}
class Thread: Content {}

但这会导致链接实体时出现问题。

您描述的内容称为 TPC 或每具体表类型关系模式,目前在实体框架核心中不受支持。您可以在此处关注相关问题。

此功能目前没有里程碑,因此,如果绝对必须执行 TPC,则唯一的选择是使用 EF6 或其他支持此关系策略的备用 ORM,而不是 EF Core。

就个人而言,我建议坚持使用 EF Core,并简单地使用 TPH(按层次结构表(或 TPT(按类型表(关系策略。前者实际上是默认值,并且将导致两者都有一个表,其中Discriminator列指示实际类型。后者是使用ToTablefluent 配置或[Table]属性时得到的,并生成一个包含所有共享属性的基类型的表,然后为每个派生类型生成一个表,仅保存该类型的属性,外键返回到基类型的表。帖子和线程之类的东西之间存在很强的关系,在数据库级别实际维护这种关系是有价值的。

最新更新