如何在NestJS中更新含一对多关联的Prisma模型的links字段
问题描述
我在NestJS中使用以下两个Prisma模型:
model DevInformations { userId Int @unique relatedUser User @relation(fields: [userId], references: [id]) name String lastName String dateOfBirth DateTime telNumber String city String zip String country String resume String? links Links[] }
model Links { id Int @id @unique @default(autoincrement()) userId Int relatedUser DevInformations @relation(fields: [userId], references: [userId]) name String link String }
创建功能正常,但更新links字段时总是触发TypeScript或NestJS错误,找不到正确的更新方式。我尝试的更新代码如下:
const devInfo = await this.prisma.devInformations.update({ where: { userId, }, data: { ...rest, links: { create: [...dto.links], }, }, include: { links: true, }, });
对应的DTO定义:
export class UpdateDevInfosDTO { @IsNumber() @IsNotEmpty() userId: number; // 其他字段省略 ....All the fields, @IsArray() links: ILinkInput[]; } export interface ILinkInput { id: number; name: string; link: string; }
解决方案
问题出在更新关联字段links时,未区分已有链接的更新和新链接的创建,Prisma对嵌套关联更新有特定语法,以下是几种常见场景的正确实现:
场景1:完全替换所有链接(删除旧链接,创建新链接)
如果想用DTO中的新链接列表完全替换旧列表,使用deleteMany+create组合:
const devInfo = await this.prisma.devInformations.update({ where: { userId }, data: { ...rest, links: { deleteMany: {}, // 删除该用户下所有旧链接 create: dto.links.map(link => ({ name: link.name, link: link.link })) // 新创建无需传id,自增字段由Prisma自动生成 } }, include: { links: true } });
场景2:混合更新(更新已有链接+新增新链接)
如果DTO中的links包含带id的已有链接和不带id的新链接,需拆分处理:
// 拆分已有链接和新链接 const existingLinks = dto.links.filter(link => link.id); const newLinks = dto.links.filter(link => !link.id); const devInfo = await this.prisma.devInformations.update({ where: { userId }, data: { ...rest, links: { // 更新已有链接 update: existingLinks.map(link => ({ where: { id: link.id }, data: { name: link.name, link: link.link } })), // 创建新链接 create: newLinks.map(link => ({ name: link.name, link: link.link })) } }, include: { links: true } });
场景3:仅更新指定链接,保留其他旧链接
如果只需要更新DTO中带id的链接,不删除或新增其他链接,仅使用update:
const devInfo = await this.prisma.devInformations.update({ where: { userId }, data: { ...rest, links: { update: dto.links.map(link => ({ where: { id: link.id }, data: { name: link.name, link: link.link } })) } }, include: { links: true } });
关键注意点
- 创建新链接时无需传递
id,Links模型的id是自增字段,Prisma会自动生成 - 嵌套更新关联字段必须使用Prisma提供的
update/create/deleteMany等专用操作符,不能直接赋值数组 - 若允许新增链接,需将
ILinkInput的id改为可选字段:
export interface ILinkInput { id?: number; name: string; link: string; }
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

