Postgres+TypeORM+NestJS疑问:创建关联订单需先查询实体吗?
关于Postgres+TypeORM+NestJS创建订单的关联字段问题
核心结论
你完全可以直接填入customer和product的ID,不需要先查询出完整实体。TypeORM支持直接通过主键值关联外键,没必要额外查库浪费性能。
两种实现方式
方式1:构造仅含主键的关联对象
不需要引入Customer/Product的Repository,直接构造包含id的对象传给Order实体:
@Injectable() export class OrderService { constructor( @InjectRepository(Order) private readonly orderRepository: Repository<Order>, ) {} async newOrder(order: OrderDto) { const newOrder = this.orderRepository.create({ customer: { id: order.customer }, // 仅传ID即可关联外键 product: { id: order.product }, }); return this.orderRepository.save(newOrder); } }
方式2:直接使用外键列名(如果实体定义了的话)
如果你的Order实体里显式定义了外键列(比如customerId、productId),可以直接赋值:
// 假设Order实体定义如下: @Entity() export class Order { @PrimaryGeneratedColumn() id: number; @Column() customerId: number; // 显式声明外键列 @Column() productId: number; @OneToOne(() => Customer) @JoinColumn({ name: 'customerId' }) customer: Customer; @OneToOne(() => Product) @JoinColumn({ name: 'productId' }) product: Product; } // 服务层代码简化为: async newOrder(order: OrderDto) { const newOrder = this.orderRepository.create({ customerId: order.customer, productId: order.product, }); return this.orderRepository.save(newOrder); }
什么时候需要查询实体?
只有当你需要验证关联实体确实存在(避免插入无效外键值),或者需要用到实体的其他属性(比如用客户名称生成订单备注)时,才需要先查询Customer/Product。示例:
async newOrder(order: OrderDto) { // 验证关联实体存在 const [customer, product] = await Promise.all([ this.customerRepository.findOneBy({ id: order.customer }), this.productRepository.findOneBy({ id: order.product }), ]); if (!customer || !product) { throw new BadRequestException('客户或产品不存在'); } const newOrder = this.orderRepository.create({ customer, product, orderNote: `客户${customer.name}下单购买${product.name}`, }); return this.orderRepository.save(newOrder); }
原代码的冗余点
原代码里的两次查询是多余的(除非你有验证需求),会额外增加数据库IO,降低接口性能。
内容的提问来源于stack exchange,提问作者Gerrit Hillebrecht
相关产品推荐
相关产品推荐

