NestJS项目中如何更简洁地实现多可选参数的实体更新逻辑?
针对你这段NestJS更新逻辑的简化方案
方案1:过滤有效字段后直接合并(无额外依赖,适配所有ORM)
该方案和你原有逻辑完全对齐,只会更新DTO中值为truthy的字段,代码量大幅减少:
async editCompany(editCompanyDto: EditCompanyDto, id: number) { const company = await this.findOne({ id }); if (!company) { throw new NotFoundException(); } // 过滤掉DTO中值为falsy的字段,对齐原if判断逻辑 const updatedFields = Object.fromEntries( Object.entries(editCompanyDto).filter(([_, value]) => value) ); // 批量合并属性到原实体对象 Object.assign(company, updatedFields); try { await this.save(company); } catch (error) { console.log(error); throw new InternalServerErrorException(); } }
说明:
- 如果你需要支持空字符串、0这类falsy值的更新,只需要把filter的条件从
value改成value !== undefined即可,只会过滤未显式传递的字段。 - 可以增加允许更新字段的白名单校验,避免DTO中多余的非法字段被写入数据库。
方案2:使用TypeORM原生preload方法(TypeORM栈专属最优解)
如果你用的是NestJS官方推荐的TypeORM作为ORM,可以直接用Repository提供的preload方法,省去手动查询+合并的全流程:
async editCompany(editCompanyDto: EditCompanyDto, id: number) { // preload会自动按id查询实体,存在则合并DTO属性,不存在返回null const company = await this.repository.preload({ id, ...editCompanyDto }); if (!company) { throw new NotFoundException(); } // 如果需要对齐原逻辑:不更新falsy值的字段,可以加这段过滤逻辑 // Object.keys(editCompanyDto).forEach(key => { // if (!editCompanyDto[key]) delete company[key]; // }); try { await this.repository.save(company); } catch (error) { console.log(error); throw new InternalServerErrorException(); } }
额外安全优化
建议新增字段白名单校验,避免前端传入未定义的字段篡改数据:
// 定义允许更新的字段白名单 const allowedFields: Array<keyof EditCompanyDto> = ['companyName', 'telNr', 'fax', 'mail', 'website', 'notes']; const updatedFields = Object.fromEntries( Object.entries(editCompanyDto) .filter(([key, value]) => allowedFields.includes(key as keyof EditCompanyDto) && value) );
内容的提问来源于stack exchange,提问作者Exo
相关产品推荐
相关产品推荐

