有一个模型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
- 包含模型
Thread
和Post
的所有属性的表Thread
为什么?
- 我假设这两个表将来都会大幅增长
- 它炸毁了我的数据库,因为表定义包含来自
Thread
行的行,这些行在Post
行上总是空
的 - 从开发人员的角度来看,它看起来并不干净和正确。
我已经尝试过的
- 在我的
DbContext
中创建两个不同的DbSet<T>
,用于Post
和Thread
为每个 - 实体添加
builder.Entity<Post>().ToTable("Post")
OnModelCreating
- 在类定义上使用
[Table("Post")]
装饰器 - 将共享属性移动到抽象的 chass 中,并让
Post
和Thread
从中继承
某种解决方法
最后一个有效:
class Content {
// Shared Attributes like Title
}
class Post: Content {}
class Thread: Content {}
但这会导致链接实体时出现问题。
您描述的内容称为 TPC 或每具体表类型关系模式,目前在实体框架核心中不受支持。您可以在此处关注相关问题。
此功能目前没有里程碑,因此,如果绝对必须执行 TPC,则唯一的选择是使用 EF6 或其他支持此关系策略的备用 ORM,而不是 EF Core。
就个人而言,我建议坚持使用 EF Core,并简单地使用 TPH(按层次结构表(或 TPT(按类型表(关系策略。前者实际上是默认值,并且将导致两者都有一个表,其中Discriminator
列指示实际类型。后者是使用ToTable
fluent 配置或[Table]
属性时得到的,并生成一个包含所有共享属性的基类型的表,然后为每个派生类型生成一个表,仅保存该类型的属性,外键返回到基类型的表。帖子和线程之类的东西之间存在很强的关系,在数据库级别实际维护这种关系是有价值的。