SQL转TypeORM查询时actual字段未返回的问题排查
问题分析与解决方案
你的TypeORM查询生成的SQL是正确的,但actual字段未被返回,核心原因是**getMany()会将结果映射到Category实体类,而你的实体类中没有定义actual属性**,TypeORM会自动忽略实体中不存在的字段。
另外注意到你TypeORM代码里的子查询中,COALESCE函数少写了第二个参数0,虽然生成的SQL里自动补上了,但建议手动添加以保持代码逻辑一致。
下面是两种可行的解决方法:
方法一:使用getRawMany()获取原始结果
getRawMany()不会映射到实体,会直接返回SQL查询的原始键值对,你可以手动处理字段名:
const rawCategories = await categoryRepository .createQueryBuilder('category') .select([ 'category.id', 'category.name', 'category.planned', 'category.type', ]) .addSelect((subQuery) => { return subQuery .select('COALESCE(SUM(transaction.amount), 0)', 'actual') .from(Transaction, 'transaction') .where('transaction.categoryId = category.id'); }, 'actual') .where('category.userId = :userId', { userId: res.locals.user.id }) .getRawMany(); // 转换为目标格式 const allCategories = rawCategories.map(item => ({ id: item.category_id, name: item.category_name, planned: item.category_planned, type: item.category_type, actual: item.actual, }));
方法二:在Category实体中添加actual临时属性
如果希望继续使用getMany(),可以在Category实体中添加一个非持久化的actual属性:
首先修改实体类:
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class Category { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column({ type: 'numeric' }) planned: number; @Column() type: string; // 添加非持久化的actual字段,select: false表示默认查询不包含该字段 @Column({ type: 'numeric', select: false }) actual: number; // 其他原有字段... }
然后修改查询代码,确保addSelect的别名与实体属性名一致:
const allCategories = await categoryRepository .createQueryBuilder('category') .select([ 'category.id', 'category.name', 'category.planned', 'category.type', ]) .addSelect((subQuery) => { return subQuery .select('COALESCE(SUM(transaction.amount), 0)', 'actual') .from(Transaction, 'transaction') .where('transaction.categoryId = category.id'); }, 'category.actual') .where('category.userId = :userId', { userId: res.locals.user.id }) .getMany();
这样getMany()就会将查询到的category.actual映射到实体的actual属性中。
内容的提问来源于stack exchange,提问作者Mush-A
相关产品推荐
相关产品推荐

