TypeORM:更新项目并返回

新手上路,请多包涵

据我所知,最好的做法是在更新后退回项目。 TypeORM 的 updateById 返回 void ,但不是更新的项目。

我的问题:是否可以在一行中更新和返回修改后的项目?

到目前为止我尝试了什么:

 await this.taskRepository.updateById(id, { state, dueDate });
return this.taskRepository.findOne({ id });

我在找什么:

 return this.taskRepository.updateById(id, { state, dueDate }); // returns updated task

原文由 sandrooco 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

我刚刚发现我可以使用 .save 方法来做到这一点:

 return this.taskRepository.save({
    id: task.id,
    state,
    dueDate
});

根据 文档(部分 save ),也支持部分更新:

由于跳过了所有未定义的属性,因此还支持部分更新。

值得注意的是, .save 如果新记录不存在,则会创建一个新记录,这可能不是故意的,有时可能会带来安全风险。为了保护这一点,您可以使用 .createQueryBuilder 在 1 个查询中实现它:

 const result = this.taskRepository.createQueryBuilder()
    .update({
        state,
        dueDate,
    })
    .where({
        id: task.id,
    })
    .returning('*')
    .execute()

return result.raw[0]

重要提示:只有 MSSQL、PostgreSQL 和 MariaDB 支持像这样使用查询构建器。

原文由 sandrooco 发布,翻译遵循 CC BY-SA 4.0 许可协议

关键是返回 response.raw[0] 以便取回类型。


虽然我想要 await Table.update({}, {}) 返回 Table 它没有。我发现使用 QueryBuilder 会更容易,因为它通常给我更多的控制权, 但是 如果你不喜欢 QueryBuilder _或者不需要它_,你可以做这样的事情:

 const post = await Post.update({id}, {...input}).then(response => response.raw[0]);
return post; // returns post of type Post

但是,如果您确实想使用 QueryBuilder 我建议采用如下方法。上面的其他人提到了 RepositoryTable.save() 并没有真正返回原始 type 在任何地方的用法,所以这种方法对我来说是不可能的。

Table.update({}, {}) 的示例:

 @Mutation(() => PostResponse, { nullable: true })
@UseMiddleware(isAuthorized)
async updatePost(
  @Arg("id", () => Int) id: number,
  @Arg("input") input: PostInput,
  @Ctx() { req }: Context
): Promise<PostResponse | null> {
  // ...
  const post = await Post.update({id}, {...input}).then(response => response.raw[0]);
  return { post };
}

QueryBuilder 的示例:

 @Mutation(() => PostResponse, { nullable: true })
@UseMiddleware(isAuthorized)
async updatePost(
  @Arg("id", () => Int) id: number,
  @Arg("input") input: PostInput,
  @Ctx() { req }: Context
): Promise<PostResponse | null> {
  // ...
  const post = await getConnection()
    .createQueryBuilder()
    .update(Post)
    .set({ ...input })
    .where('id = :id and "creatorId" = :creatorId', {
      id,
      creatorId: userId,
    })
    .returning("*")
    .execute()
    .then((response) => {
      return response.raw[0];
    });

  return { post };
}


辅助函数 (如果你不想一直写 response.raw[0]

 const typeReturn = async <T>(mutation: Promise<UpdateResult | DeleteResult | InsertResult>): Promise<T> => {
  return await mutation.then((res) => res.raw[0]);
};

用法:

 const update = await typeReturn<Post>(Post.update(...));
const insert = await typeReturn<Attachment>(Attachment.insert(...));
const del    = await typeReturn<User>(User.delete(...));

注意:我在这里使用 TypeORM 和 Type-GraphQL。

.returning("*") 不适用于 MySQL,请参阅下面的评论。

原文由 Joel 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进