据我所知,最好的做法是在更新后退回项目。 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
我刚刚发现我可以用
.save
方法做到这一点:
return this.taskRepository.save({
id: task.id,
state,
dueDate
});
根据文档(
save
部分),也支持部分更新:
还支持部分更新,因为所有未定义的属性都被跳过。
为了扩展 sandrooco 的答案,这就是我所做的:
const property = await this.propertyRepository.findOne({
where: { id }
});
return this.propertyRepository.save({
...property, // existing fields
...updatePropertyDto // updated fields
});
response.raw[0]
以取回类型。虽然我想要
await Table.update({}, {})
返回Table
但它没有。我发现使用 QueryBuilder
更容易,因为它总体上给了我更多的控制权,BUT 如果你不喜欢 QueryBuilder
或者不需要它,你可以做类似的事情这个:
const post = await Post.update({id}, {...input}).then(response => response.raw[0]);
// or
const post = (await Post.update({id}, {...input})).raw?.[0];
return post; // returns post of type Post
但是,如果您确实想使用
QueryBuilder
,我建议采用如下方法。
上面的其他人提到了 Repository
和 Table.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> {
//...
Post.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).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,请参阅下面的评论。
一种方法是执行更新,然后根据您指定的条件进行查找
让我们这样做来验证
.save
方法是否存在,
async findOne(id: string): Promise<Manufacturer> {
const found = await this.repository.findOneBy({ id });
if (!found) {
throw new NotFoundException(`Could not find ${this.Entity.name} with id: ${id}`);
}
return found;
}
async update(id: string, updateEmployeeDto: UpdateManufacturerDto): Promise<Manufacturer> {
await this.findOne(id);
return this.repository.save({ id, ...updateEmployeeDto });
}