Nestjs+TypeORM中正确保存和更新实体

Correctly Saving and Updating Entites in Netsjs+TypeORM

我有一个关于 TypeORM-Relations 以及如何使用它们的问题 'nest-like'。

假设我定义了两个相关的实体 ChildEntityTestEntity

TestEntity:

import { ChildEntity } from 'src/modules/child-entity/entities/child-entity.entity';
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class TestEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('varchar')
  name: string;

  @ManyToOne(() => ChildEntity, (childEntity) => childEntity.testEntities)
  childEntity: ChildEntity;

  constructor(name: string, childEntity: ChildEntity) {
    this.name = name;
    this.childEntity = childEntity;
  }
}

我想创建实体时出现了第一个问题。我必须首先将传递的 childEntityId 翻译成 ChildEntity,我可以将其传递给构造函数:

CreateTestEntityDto

import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsNumber } from 'class-validator';

export class CreateTestEntityDto {
  @ApiProperty()
  @IsNotEmpty()
  name: string;

  @ApiProperty()
  @IsNumber()
  childEntityId: number;

  constructor(name: string, childEntityId: number) {
    this.name = name;
    this.childEntityId = childEntityId;
  }
}

  async create(createTestEntityDto: CreateTestEntityDto) {
    const { name, childEntityId } = createTestEntityDto;
    const childEntity = await this.childEntityService.findOne(childEntityId);
    const testEntity = new TestEntity(name, childEntity);
    return this.testEntityRepo.save(testEntity);
  }

有没有一种方法可以直接将 childEntityId 传递给 save()-Method 而无需事先明确查找 ChildEntity


更新时出现第二个问题

UpdateTestEntityDto

import { PartialType } from '@nestjs/swagger';
import { CreateTestEntityDto } from './create-test-entity.dto';

export class UpdateTestEntityDto extends PartialType(CreateTestEntityDto) {}

因为只更新部分实体是可能的,所以我必须检查 Id 是否随请求一起传递,如果是,我必须检索正确的实体以进行更新。有没有更简化的方法来做到这一点?

  async update(id: number, updateTestEntityDto: UpdateTestEntityDto) {
    const { name, childEntityId } = updateTestEntityDto;
    const props = { name };
    if (childEntityId) {
      props['childEntity'] = await this.childEntityService.findOne(
        childEntityId,
      );
    }
    return this.testEntityRepo.update(id, props);
  }

你应该添加一个childEntityId到测试实体:

@Entity()
export class TestEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('varchar')
  name: string;

  @Column('int')
  childEntityId: number;

  @ManyToOne(() => ChildEntity, (childEntity) => childEntity.testEntities)
  childEntity: ChildEntity;

  ...
}

然后就可以直接用它来设置id了。类似于:

async create(dto: Dto) {
    const { name, childEntityId } = dto;

    const entity = new TestEntity();
    entity.name = name;
    entity.childEntityId = childEntityId;

    return this.testEntityRepo.save(entity);
}

检查 this

1.) 保存关系实体

无需为了保存实体而进行所有这些混乱的往返。虽然,@UrosAndelic 给出的解决方案有效,但仍然不需要编写 3 行额外的代码。

如果您将鼠标悬停在 IDE 存储库的 create() 方法内的关系参数上,您会注意到它接受两种类型。首先,实体的 Instance 或第二,实体的 DeepPartial 对象。

例如:

const entity = this.testEntityRepo.create({
   name: 'Example 1',
   childEntity: {
      id: childEntityId // notice: it's a DeepPartial object of ChildEntity
   }
})

await this.testEntityRepo.save(entity)

2.) 更新实体

如果您要更新测试实体,则不需要子实体的 ID。您可以简单地更新测试实体的道具。

const testEntityId = 1;

await this.testEntityRepo.update(testEntityId, {
   name: 'Example 2'
})

这将更新 TestEntity = 1name