TypeORM@0.2.5多对多关联中基于关联实体字段查询的问题
嘿,我碰到过类似的TypeORM 0.2.x版本多对多查询的坑,给你几个靠谱的解决办法!
问题原因分析
你遇到的报错Unknown column 'MyEntity.myEntityId' in 'where clause',本质是TypeORM 0.2.x的find方法没法自动解析多对多关联的中间表逻辑。当你直接在where里写rel: myValue或者rel: {id: myValue}时,它会错误地尝试直接从MyEntity表中找关联字段,而不是通过中间表关联查询。
解决方案
方法1:使用QueryBuilder(最推荐,和你预期的SQL完全一致)
QueryBuilder可以手动控制关联逻辑,完美匹配你想要的SQL语句:
const myEntities = await this.entityRepo.createQueryBuilder('m') // 这里的'm.rel'对应MyEntity类中定义的多对多关联属性名 .leftJoin('m.rel', 'r') // 用参数绑定避免SQL注入 .where('r.id = :searchId', { searchId: mySearchKey }) .getMany();
这段代码会生成和你预期几乎一样的SQL:
SELECT m.* FROM my_entity_table m LEFT JOIN my_rel_pivot_table mrp ON mrp.my_entity_id = m.id LEFT JOIN rel_entity_table r ON r.id = mrp.rel_entity_id WHERE r.id = ?
方法2:用子查询+In条件实现find方法查询
如果你更习惯用find方法,可以先通过子查询拿到符合条件的MyEntity ID列表,再用In条件过滤:
import { In } from 'typeorm'; // 第一步:从中间表查询匹配RelEntity的MyEntity ID const matchedMyEntityIds = await this.entityRepo.manager .createQueryBuilder() .select('mrp.my_entity_id', 'entityId') .from('my_rel_pivot_table', 'mrp') .where('mrp.rel_entity_id = :targetId', { targetId: mySearchKey }) .getRawMany(); // 第二步:用In条件查询对应的MyEntity实例 const myEntities = await this.entityRepo.find({ where: { id: In(matchedMyEntityIds.map(item => item.entityId)) } });
方法3:检查实体关联定义是否正确
有时候报错是因为实体的多对多关联配置有误,确保你的实体定义和中间表匹配:
MyEntity的正确配置示例:
import { Entity, PrimaryGeneratedColumn, ManyToMany, JoinTable } from 'typeorm'; import { RelEntity } from './RelEntity'; @Entity('my_entity_table') export class MyEntity { @PrimaryGeneratedColumn() id: number; // 其他属性... @ManyToMany(() => RelEntity) @JoinTable({ name: 'my_rel_pivot_table', // 必须和自动生成的中间表名一致 joinColumn: { name: 'my_entity_id', referencedColumnName: 'id' }, inverseJoinColumn: { name: 'rel_entity_id', referencedColumnName: 'id' } }) rel: RelEntity[]; // 这个属性名要和你查询时用的一致 }
RelEntity的双向关联配置(如果需要):
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from 'typeorm'; import { MyEntity } from './MyEntity'; @Entity('rel_entity_table') export class RelEntity { @PrimaryGeneratedColumn() id: number; @Column() prop: string; @ManyToMany(() => MyEntity, myEntity => myEntity.rel) myEntities: MyEntity[]; }
总结
最推荐用QueryBuilder,它完全贴合你想要的SQL逻辑,而且在复杂关联查询时更灵活可控。如果一定要用find方法,子查询+In的方式也能解决问题。另外记得检查实体关联的配置,确保中间表名、关联字段名和数据库实际生成的一致。
内容的提问来源于stack exchange,提问作者Colum
相关产品推荐
相关产品推荐

