能否通过Prisma关联关系构建含引用属性的自定义对象?
你的Prisma关联方案不可行,正确实现方式看这里
直接用自定义Author类型作为关联的fields参数是行不通的,原因很简单:Prisma的关联关系要求fields必须指向模型中的标量字段,而你定义的Author属于复合类型,无法被识别为关联所需的外键字段。另外你当前的模型还有个小问题:User里的name和email是可选字段,但Author类型里这两个字段是必填的,会导致数据写入时出现不一致的冲突。
下面给你两种可行的实现方案,按需选择:
方案1:用复合类型存嵌入式作者信息,同时保留标量字段做关联
如果想在Post里用author嵌入式对象存储信息,同时维持和User的关联,需要保留对应的标量外键字段,再用复合类型把这些字段映射成对象:
model User { id String @id @default(cuid()) @map("_id") name String? email String? @unique posts Post[] } model Post { id String @id @default(auto()) @map("_id") @db.ObjectId title String description String // 保留关联所需的标量外键字段,可选性和User保持一致 authorId String authorEmail String? authorName String? // 用复合类型把标量字段映射成嵌入式文档 author Author @map("author") // 关联关系依然指向标量字段 user User @relation(fields: [authorId, authorEmail, authorName], references: [id, email, name]) } // 复合类型的字段可选性要和User模型匹配 type Author { id String name String? email String? }
这种方式下,数据库里的Post文档会有一个author嵌入式对象,同时关联关系依然能正常工作。
方案2:不存冗余数据,直接通过关联查询获取作者信息
如果不需要在Post里存储作者的冗余信息,完全可以只保留authorId作为外键,查询时通过关联获取User的信息:
model User { id String @id @default(cuid()) @map("_id") name String? email String? @unique posts Post[] } model Post { id String @id @default(auto()) @map("_id") @db.ObjectId title String description String authorId String user User @relation(fields: [authorId], references: [id]) }
查询时用include或select拿到作者信息,之后可以自行重命名为author:
const postWithUser = await prisma.post.findUnique({ where: { id: "你的帖子ID" }, include: { user: { select: { id: true, name: true, email: true } } } }); // 把user字段转成author const post = { ...postWithUser, author: postWithUser.user, user: undefined };
内容的提问来源于stack exchange,提问作者user7043436
相关产品推荐
相关产品推荐

