TypeORM createQueryBuilder是否支持传入字符串表名替代实体类查询?
解决方案
方法1:使用官方支持的EntitySchema动态构造临时实体(最推荐,完全符合规范)
TypeORM的EntitySchema是官方提供的用于动态定义实体的API,不需要提前写死类装饰器,完美适配动态表名场景:
import { EntitySchema } from 'typeorm'; // 获取动态生成的表名 const tableName = await getDynamicallyGenetaredTableNames().getFirstOne(); // 构造动态实体Schema const DynamicTable = new EntitySchema({ // 直接传入动态表名作为实体名 name: tableName, columns: { // 仅需要声明任意一个存在的主键列即可,不需要匹配全表字段 // 因为你使用`getRawMany`拿原始结果,不需要实体映射逻辑 id: { type: 'int', primary: true } } }); // 正常传入QueryBuilder即可,无类型报错,完全符合TypeORM设计 return await getManager() .createQueryBuilder() .select('*') .from(DynamicTable, 'tableAlias') .getRawMany();
优化点
- 如果动态表有统一的结构,可以提前定义基础字段模板,复用Schema构造逻辑
- 如果需要返回值类型提示,可以给
EntitySchema传入泛型:new EntitySchema<YourReturnType>(...),最终getRawMany的结果会自动获得对应的TS类型
方法2:表名直接传参(运行时支持,仅类型层面适配)
你碰到的类型报错只是TS类型定义的限制,TypeORM运行时本身就支持from方法直接传入字符串表名,如果你不想构造EntitySchema,可以通过重载类型定义的方式解决,而非直接类型断言:
- 全局添加TypeORM类型扩展:
// typeorm.d.ts import { QueryBuilder } from 'typeorm'; declare module 'typeorm' { interface QueryBuilder<Entity> { from(tableName: string, alias: string): this; } }
- 之后就可以直接传入字符串表名,无类型报错:
const tableName = await getDynamicallyGenetaredTableNames().getFirstOne(); return await getManager() .createQueryBuilder() .select('*') .from(tableName, 'tableAlias') .getRawMany();
注意:该方法仅推荐你确定动态表名都是合法、无SQL注入风险的场景下使用,优先推荐方法1。
内容的提问来源于stack exchange,提问作者SeekanDestroy
相关产品推荐
相关产品推荐

