TypeORM如何实现三层一对一关联及关联查询?
TypeORM三层一对一关联查询解决方案
先修正实体定义中的错误
你的实体代码里存在两处类型定义错误,会导致关联映射异常:
Person类中meta属性的类型应为PersonMeta,而非MetaDBHouse类中owner属性的类型应为Person,而非FNodeDB
修正后的实体代码:
@Entity({ name: 'person' }) export class Person extends BaseEntity { @PrimaryColumn({ type: 'varchar' }) key!: string; @OneToOne(() => PersonMeta, { cascade: true }) @JoinColumn({ name: 'key', referencedColumnName: 'key', foreignKeyConstraintName: 'metaKey' }) meta!: PersonMeta; // 修正类型 } @Entity({ name: 'personMeta' }) export class PersonMeta extends BaseEntity { @PrimaryColumn({ type: 'varchar' }) key!: string; @Column() @Index() age!: number; } @Entity({ name: 'house' }) export class House extends BaseEntity { @PrimaryColumn({ type: 'varchar' }) key!: string; @OneToOne(() => Person, { cascade: true }) @JoinColumn({ name: 'owner', referencedColumnName: 'key', foreignKeyConstraintName: 'ownerKey' }) owner!: Person; // 修正类型 }
正确的三层关联查询方式
你之前的查询代码存在两个核心问题:
- 拼写错误:
relation应为relations - 未嵌套加载关联:要获取
owner的meta,需要在relations中通过嵌套对象声明层级
方式一:使用findOne嵌套加载关联
// 注意添加await,你之前的代码漏掉了异步处理 const owner = await Person.findOneBy({ key: 'xxx', name: 'eczn' }); if (!owner) throw new Error('not found'); const house = await House.findOne({ relations: { owner: { meta: true } }, // 嵌套声明需要加载的关联层级 where: { owner }, }); if (house) { console.log('house owner age is:', house.owner.meta.age); // 可正常获取age }
方式二:使用QueryBuilder实现灵活查询
如果需要更复杂的过滤条件,推荐使用QueryBuilder:
const house = await House.createQueryBuilder('house') .leftJoinAndSelect('house.owner', 'owner') .leftJoinAndSelect('owner.meta', 'meta') .where('owner.key = :key', { key: 'xxx' }) .andWhere('owner.name = :name', { name: 'eczn' }) .getOne(); if (house) { console.log('house owner age is:', house.owner.meta.age); }
关键注意点
- TypeORM加载多层关联时,必须通过嵌套对象的形式在
relations中声明所有需要加载的层级 - 实体间的关联字段类型必须与目标实体一致,否则会导致映射失败
- 异步查询必须添加
await,避免拿到Promise对象而非实际数据
内容的提问来源于stack exchange,提问作者eczn
相关产品推荐
相关产品推荐

