You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:50:24