如何使用 TypeORM 中的 QueryBuilder 更新具有关系的实体

How to update an entity with relations using QueryBuilder in TypeORM

我有UserEntityAddressEntity,它们的关系是OneToOne,也就是说一个用户可能只有一个地址。 UserEntity 有字段 firstNamesecondNameaddressAddressEntity 有字段 countrycity.

如果我想更新 UserEntity 而不对其关系进行更新,我会这样做:

      await entityManager.getRepository(UserEntity)
                         .createQueryBuilder('users')
                         .update(UserEntity)
                         .set(updateUserObject)
                         .where('users.id = :userId', { userId })
                         .execute();

其中 updateUserObject 由请求正文构成。也就是说,如果我需要更新 firstName,对象将如下所示:{ firstName: 'Joe' }。现在不清楚的是如果我有以下 updateUserObject:

如何使用该构建器
{
    firstName: "Bob",
    address: {
        "city": "Ottawa"
    }
}

官方文档没有解决这种情况。

您可以使用 preload and save 方法实现此目的。

更新您的 UserEntity 类似于以下内容:

@Entity('user')
export class UserEntity {
  ...

  @OneToOne(
    () => AddressEntity,
    {
      // Make sure that when you delete or update a user, it will affect the
      // corresponding `AddressEntity`
      cascade: true,
      // Make sure when you use `preload`, `AddressEntity` of the user will also
      // return (This means whenever you use any kind of `find` operations on
      // `UserEntity`, it would load this entity as well)
      eager: true
    }
  )
  @JoinColumn()
  address: AddressEntity;
}

现在使用 entityManager,您可以使用以下方式更新您想要的所有字段:

const partialUserEntity = {
    id: userId,
    firstName: "Bob",
    address: {
        "city": "Ottawa"
    }
};

const userRepository = await entityManager.getRepository(UserEntity);

// Here we load the current user entity value from the database and replace
// all the related values from `partialUserEntity`
const updatedUserEntity = userRepository.preload(partialUserEntity);

// Here we update (create if not exists) `updatedUserEntity` to the database
await userRepository.save(updatedUserEntity);

但是,您需要确保您的 UserEntity 始终关联一个 AddressEntity。否则,在执行 save 方法之前,您必须像下面那样为 AddressEntity 生成一个 id

/* 
 * If `updatedUserEntity.address.id` is `undefined`
 */

// `generateIDForAddress` is a function which would return an `id`
const generatedIDForAddress = generateIDForAddress();
const partialUserEntity = {
    id: userId,
    firstName: "Bob",
    address: {
        "id": generatedIDForAddress,
        "city": "Ottawa"
    }
};

请注意,在后台,typeorm 将 运行 UPDATE 语句分别用于 UserEntityAddressEntity。这只是对多个join语句(执行preload方法时)和update语句(执行save方法时)的封装,开发者可以很容易的实现这个场景。

希望对您有所帮助。干杯!