TypeORM多对多关联查询:如何直接返回关联表table2的数据?
解决TypeORM多对多关联返回table2数组的问题
一、查询结果映射(快速解决)
如果不想修改现有实体结构,可在查询完成后手动提取table2数据:
// 执行查询获取原始结果 const rawTable1List = await qb.getMany(); // 转换结构,提取table2数组 const formattedList = rawTable1List.map(item => ({ ...item, table2: item.table1table2.map(rel => rel.table2), // 可选:移除中间表字段 table1table2: undefined }));
这种方式无需调整查询语句,仅对返回结果做一次映射转换即可得到目标结构。
二、调整实体关联定义(推荐方案)
若希望TypeORM直接返回table2数组,需修正table1实体的关联定义,直接使用@ManyToMany并指定自定义中间表,而非通过中间表实体间接关联:
实体示例
table1.entity.ts
import { Entity, PrimaryGeneratedColumn, ManyToMany, JoinTable } from "typeorm"; import { Table2 } from "./table2.entity"; @Entity() export class Table1 { @PrimaryGeneratedColumn() id: number; // 其他业务字段... // 直接定义多对多关联,绑定自定义中间表 @ManyToMany(() => Table2) @JoinTable({ name: "table1table2", // 你的中间表名 joinColumn: { name: "table1Id", referencedColumnName: "id" }, inverseJoinColumn: { name: "table2Id", referencedColumnName: "id" } }) table2: Table2[]; // 直接映射为table2数组 }
table2.entity.ts
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"; import { Table1 } from "./table1.entity"; @Entity() export class Table2 { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column() disabled: number; // 可选:添加反向关联 @ManyToMany(() => Table1, table1 => table1.table2) table1s: Table1[]; }
注:如果中间表
table1table2仅包含关联ID字段,无需单独创建中间表实体;若有额外业务字段(如创建时间),则需用@OneToMany+@ManyToOne关联中间表,此时只能通过结果映射提取table2数据。
简化后的查询函数
实体调整后,查询逻辑可简化为:
async addTable2Details(qb: SelectQueryBuilder<Table1>) { qb.leftJoinAndSelect('table1.table2', 'table2'); }
此时返回结果会直接包含table2数组,完全符合你的需求。
三、纠正认知误区
.select(['table1','table2'])无效的原因:你之前的实体关联是table1→table1table2→table2,TypeORM会严格按照实体的关联层级返回结构,即使选择table2字段,数据仍会嵌套在table1table2下,无法直接平级返回。- 连接后必须选字段:这个规则是对的,但选择字段仅决定返回哪些数据,无法改变实体关联定义的结构层级。要改变返回结构,要么调整实体关联,要么手动映射结果。
内容的提问来源于stack exchange,提问作者Sescada
相关产品推荐
相关产品推荐

