TypeORM查询如何按类型返回关联Resource子类的完整字段?
解决方案
要让TypeORM查询SuperResource时自动加载resource字段对应的子类完整信息,只需配置类表继承策略并设置鉴别器,无需二次查询,具体步骤如下:
1. 配置Resource抽象类的继承规则
在抽象Resource实体上添加继承策略和鉴别器列,让TypeORM能识别子类类型:
@Entity() @TableInheritance({ column: { type: "varchar", name: "type" } }) export abstract class Resource extends BaseEntity { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column() regulatory: boolean; }
这里@TableInheritance指定用type列存储子类标识,和你SuperResource中的type字段对应,避免冗余。
2. 为子类设置鉴别器值
在每个Resource子类上添加@DiscriminatorValue,绑定到ResourceTypes枚举的对应值:
Job子类修改:
@Entity() @DiscriminatorValue(ResourceTypes.Job) export class Job extends Resource { @Column() jobId: number; @Column() description: string; }
Table子类修改:
@Entity() @DiscriminatorValue(ResourceTypes.Table) export class Table extends Resource { @Column() description: string; @Column() database: string; @Column({ type: 'enum', enum: Datasources, default: Datasources.Other}) datasource: Datasources; }
注意:子类无需重复定义主键,直接继承父类的id即可。
3. 执行查询并访问子类字段
现在执行原查询语句,resource字段会自动加载对应子类的完整数据:
const superResource = await repository.findOne({ where: {id: parseInt(id)} });
可以通过类型判断直接访问子类专属字段:
if (superResource.resource instanceof Job) { console.log(superResource.resource.jobId); } else if (superResource.resource instanceof Table) { console.log(superResource.resource.database); }
关键说明
- 类表继承(
JOINED模式)会让父类、子类分别对应独立数据库表,查询时TypeORM自动执行左连接,一次性拉取所有字段。 - 若子类字段差异小,也可改用单表继承(
SINGLE_TABLE),所有子类数据存在同一张表,通过鉴别器列区分,但会产生较多空字段。
内容的提问来源于stack exchange,提问作者Manuel
相关产品推荐
相关产品推荐

