Prisma定义Product与Category关联后Apollo Studio查询无关联数据
实现目标
查询Product数据时,同步返回商品所属的Category分类信息。
当前配置
Prisma Schema
当前定义的模型如下,已配置Product与Category的关联关系,Prisma Studio中可正常看到关联配置:
model Product { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String @db.VarChar(80) description String @db.VarChar(240) ingredients String[] price Float category Category[] } model Category { id String @id @default(uuid()) createdAt DateTime @default(now()) name String product Product[] }
现有Resolver代码
export const resolvers = { Query: { allCategories:(_parent:any, _args:any, context: Context) => { return context.prisma.category.findMany() }, allProducts:(_parent:any, _args:any, context:Context) => { return context.prisma.product.findMany() }, productById:(_parent: any, {id}, context: Context) => { return context.prisma.product.findUnique({ where: { id } }) }, categoryById:(_parent:any, {id}, context: Context) => { return context.prisma.category.findUnique({ where: { id } }) }, productsByCategory:(_parent:any, {category}, context: Context) => { return context.prisma.product.findMany({ select: { category: true } }) } },
异常表现
Apollo Studio中执行查询时,关联的分类字段无法正常展示,相关截图如下:

问题原因
- Prisma默认不会自动加载关联表数据,所有关联查询必须显式声明要加载的关联字段,现有查询逻辑未声明加载category关联,返回结果中自然没有对应数据。
- GraphQL采用字段级解析逻辑,仅在Query下写查询方法不够,类型自身的关联字段需要单独配置Resolver,否则GraphQL无法自动获取关联数据。
- 现有
productsByCategory方法逻辑错误:未根据传入的分类参数做过滤,且select配置仅返回category字段,丢失了Product本身的其他属性。
修复方案
1. 补全关联查询逻辑与类型Resolver
在现有resolvers配置中,查询时显式声明加载关联字段,同时新增Product和Category类型的关联字段解析逻辑兜底,修改后完整代码如下:
export const resolvers = { Query: { allCategories:(_parent:any, _args:any, context: Context) => { return context.prisma.category.findMany({ include: { product: true } }) }, allProducts:(_parent:any, _args:any, context:Context) => { // 查询时直接include关联数据,减少额外查询次数 return context.prisma.product.findMany({ include: { category: true } }) }, productById:(_parent: any, {id}, context: Context) => { return context.prisma.product.findUnique({ where: { id }, include: { category: true } }) }, categoryById:(_parent:any, {id}, context: Context) => { return context.prisma.category.findUnique({ where: { id }, include: { product: true } }) }, productsByCategory:(_parent:any, {categoryId}, context: Context) => { // 修正原有逻辑:按分类ID过滤,返回完整商品数据+关联信息 return context.prisma.product.findMany({ where: { category: { some: { id: categoryId } } }, include: { category: true } }) } }, // 类型级Resolver,处理关联字段解析 Product: { category: (parent, _args, context) => { // 父级查询已返回category时直接复用,否则触发单独查询 return parent.category ?? context.prisma.product.findUnique({ where: { id: parent.id }}).category() } }, Category: { product: (parent, _args, context) => { return parent.product ?? context.prisma.category.findUnique({ where: { id: parent.id }}).product() } } }
2. 校验关联关系是否匹配业务场景
当前Schema配置的是Product与Category的多对多关系(一个商品属于多个分类,一个分类下有多个商品),如果实际业务为一个商品仅属于一个分类,需要修改Schema为一对多关系,示例如下:
model Product { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String @db.VarChar(80) description String @db.VarChar(240) ingredients String[] price Float categoryId String category Category @relation(fields: [categoryId], references: [id]) } model Category { id String @id @default(uuid()) createdAt DateTime @default(now()) name String product Product[] }
修改完成后执行npx prisma migrate dev同步数据库结构即可。
内容的提问来源于stack exchange,提问作者Esore
相关产品推荐
相关产品推荐

