TypeORM查询时自定义计算列值如何通过getMany返回实体结果
TypeORM 自定义计算字段
getMany() 无法获取问题解决方案 问题根因
TypeORM 的
getMany()方法会将查询结果自动映射到对应实体类的实例中,所有未在实体类中定义的字段会在映射阶段被直接丢弃;而getRawMany()直接返回数据库查询的原始结果,不做实体映射校验,因此可以正常拿到自定义计算的points字段。
方案1:在实体类中新增映射字段(推荐)
步骤1:修改ContractPoint实体类,新增points字段
TypeORM 0.3.x+ 版本可以使用@VirtualColumn标记为虚拟计算字段,不会持久化到数据库:
import { Entity, Column, VirtualColumn } from 'typeorm'; @Entity() export class ContractPoint { // 原有其他字段保持不变 // ... // 新增虚拟计算字段 @VirtualColumn({ type: 'int' }) points: number; }
低于0.3.x的旧版本TypeORM,可以用普通@Column标记为非持久化字段:
@Column({ type: 'int', nullable: true, select: false, insert: false, update: false }) points: number;
步骤2:修改查询语句,调整计算字段别名
按照TypeORM的实体映射别名规则,自定义字段别名需要遵循[实体别名]__[字段名]的格式,才能自动映射到实体属性:
const contractPoints = await getRepository(ContractPoint).createQueryBuilder('contractPoint') // 调整别名,匹配实体字段映射规则 .addSelect( 'contractPoint.point + COALESCE((SELECT SUM(cpHistory.point_change) FROM contract_point_history AS cpHistory WHERE cpHistory.contract_point_id = contractPoint.id), 0)', 'contractPoint__points' ) .andWhere('EXTRACT(YEAR FROM contractPoint.validFrom) = :year', { year }) .andWhere('contractPoint.contractId = :contractId', { contractId }) .orderBy('contractPoint.grantedAt', OrderByDirection.Desc) .getMany();
修改后直接调用getMany()即可正常获取points字段。
方案2:不修改实体,手动合并字段
如果不想修改实体结构,可以使用getRawAndEntities()方法同时获取实体和原始查询结果,手动合并计算字段:
const { entities, raw } = await getRepository(ContractPoint).createQueryBuilder('contractPoint') .addSelect( 'contractPoint.point + COALESCE((SELECT SUM(cpHistory.point_change) FROM contract_point_history AS cpHistory WHERE cpHistory.contract_point_id = contractPoint.id), 0)', 'points' ) .andWhere('EXTRACT(YEAR FROM contractPoint.validFrom) = :year', { year }) .andWhere('contractPoint.contractId = :contractId', { contractId }) .orderBy('contractPoint.grantedAt', OrderByDirection.Desc) .getRawAndEntities(); // 手动合并计算字段到实体实例 const contractPoints = entities.map((entity, index) => ({ ...entity, points: raw[index].points }));
内容的提问来源于stack exchange,提问作者Daniyar Changylov
相关产品推荐
相关产品推荐

