You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:47:04