如何在TypeORM中避免二次查询,直接用UserID保存关联Event?
解决TypeORM关联时避免查询User对象的两种方法
方案一:显式定义外键字段
在Event实体里同时定义关联对象createdBy和对应的外键字段createdById,直接通过赋值外键ID完成关联,无需查询User对象。
修改后的Event实体:
import { Entity, PrimaryGeneratedColumn, Column, JoinColumn, ManyToOne, } from 'typeorm'; import { User } from './User'; @Entity() export class Event { @PrimaryGeneratedColumn() id: number; @Column() eventName: string; // 显式声明外键字段 @Column() createdById: number; @ManyToOne(() => User) @JoinColumn({ name: 'createdById' }) // 指定外键列与上面的createdById对应 createdBy: User; } export default Event;
对应修改后的控制器代码:
const EventRepository = AppDB.getRepository(Event); export async function addEvent(userID: number, eventObject: EventObject) { const e = new Event(); Object.assign(e, eventObject); e.eventStart = new Date(eventObject.eventStart); e.eventEnd = new Date(eventObject.eventEnd); e.createdById = userID; // 直接赋值userID即可完成关联 await EventRepository.save(e); return e; }
保存时TypeORM会自动处理关联逻辑,不会触发额外的User表查询。
方案二:使用TypeORM的引用对象(无需修改实体)
如果不想改动实体结构,可通过TypeORM提供的getReferenceById方法创建User的引用对象——这个对象不会触发数据库查询,仅用于关联外键。
修改后的控制器代码:
const userRepository = AppDB.getRepository(User); const EventRepository = AppDB.getRepository(Event); export async function addEvent(userID: number, eventObject: EventObject) { const e = new Event(); Object.assign(e, eventObject); e.eventStart = new Date(eventObject.eventStart); e.eventEnd = new Date(eventObject.eventEnd); // 创建User引用对象,不执行数据库查询 e.createdBy = userRepository.getReferenceById(userID); await EventRepository.save(e); return e; }
TypeORM会识别这是关联引用,插入Event时直接将userID写入外键字段,省去查询User的步骤。
内容的提问来源于stack exchange,提问作者Rex
相关产品推荐
相关产品推荐

