TypeORM查询ManyToOne关联嵌套User对象返回null无对应SQL如何解决?
问题解决方法
首先明确核心原因:TypeORM默认不会自动加载关联实体,只有主动指定加载策略时才会触发关联表的SELECT查询,这就是你日志里没有User表查询语句、user字段返回null的根本原因。
你可以选择以下任意一种方案解决:
方案1:查询时主动指定关联加载
修改你cartItems查询对应的Resolver代码,在查询CartItem时通过relations参数声明要加载的关联:
// 原查询逻辑如果是这样 const cartItems = await CartItem.find() // 修改为 const cartItems = await CartItem.find({ relations: ['user'] })
如果是用findOne查询单个CartItem,写法同理:
const cartItem = await CartItem.findOne({ where: { id: xxx }, relations: ['user'] })
方案2:设置关联自动预加载
如果每次查询CartItem都需要用到关联的User对象,可以直接在实体的关联装饰器中加eager: true配置,之后所有CartItem查询都会自动加载User关联,不需要每次手动加relations参数:
// 修改CartItem.ts中的@ManyToOne装饰器 @Field(() => User, { nullable: true }) @ManyToOne((type) => User, (user) => user.cartItems, { eager: true }) user: User;
方案3:使用TypeGraphQL字段解析器按需加载
如果不是所有CartItem查询都需要User关联,更推荐用字段解析器实现按需加载,只有GraphQL请求中包含user字段时才会触发关联查询,性能更优:
在你的CartItem Resolver中新增字段解析器逻辑:
import { FieldResolver, Root } from "type-graphql"; // 放在CartItem对应的Resolver类中 @FieldResolver(() => User) async user(@Root() cartItem: CartItem) { return await User.findOneBy({ id: cartItem.userId }); }
额外注意点
你当前的createCartItem Mutation返回的新建CartItem对象默认也不会带关联User,如果需要返回带User的结果,创建完成后需要主动加载关联再返回:
async createCartItem( @Arg("input") input: CartItemInput, @Ctx() { req }: MyContext ): Promise<CartItem> { const newCart = await CartItem.create({ quantity: input.quantity, userId: req.session.userId, mealkitId: input.mealkitId, }).save(); // 加载关联后返回 return await CartItem.findOne({ where: { id: newCart.id }, relations: ['user'] }); }
内容的提问来源于stack exchange,提问作者Kittichote Chain
相关产品推荐
相关产品推荐

