TypeORM结合type-graphql下1对1关联Profile实体按需更新问题
问题修复与优化方案
现有代码问题分析
- QueryBuilder使用错误:TypeORM的
update方法执行后返回的是UpdateResult对象,无法直接通过.getOne()获取更新后的Profile实体,导致后续user.profile赋值逻辑不生效。 - 冗余重复的
where条件:同一个查询逻辑中两次编写.where("id = :id", { id: user.profile.id }),属于无效冗余代码。 - 字段判断逻辑冗余:逐个编写
if判断字段是否存在的写法可维护性差,后续新增更新字段需要额外补充判断逻辑。
优化实现方案
核心优化点
- 自动过滤未传值字段:通过对象属性遍历过滤
undefined值,无需逐个写if判断,后续新增字段只需在updatableFields中添加即可。 - 修复Profile更新逻辑:修正TypeORM更新、查询实体的错误写法,保证数据更新后能正确返回。
- 简化数据库操作:移除不必要的
user.save()调用(未修改User表字段无需执行保存)。
优化后代码
@Resolver() export class UpdateAccountResolver { @Mutation(() => UpdateProfileObjectType) async updateProfile( @Ctx() {}: UserContext, @Arg("input", () => UpdateInput) { avatar, bio, email, gender, verified, username, status, phoneNumber, userId, }: UpdateInput ): Promise<UpdateProfileObjectType> { const user = await User.findOne({ where: { id: userId }, relations: ["profile", "posts"], }); if (!user) { return { error: { field: "user", message: "could not find the user with a given id.", }, }; } // 自动过滤未传值的undefined字段,无需逐个if判断 const updatableFields = { bio, email, gender, verified, username, status, phoneNumber }; const profileObject = Object.fromEntries( Object.entries(updatableFields).filter(([_, value]) => value !== undefined) ) as any; // 单独处理avatar上传逻辑 try { if (avatar) { const { secure_url } = await cloudinary.uploader.upload(avatar, { public_id: `${user.id}:${uuid_v4()}`, upload_preset: "likeme", folder: "avatars", }); profileObject.avatar = secure_url; } } catch (err) { console.log(err); } // 执行Profile更新 await Profile.update({ id: user.profile.id }, profileObject); // 查询更新后的最新Profile数据 const updatedProfile = await Profile.findOneBy({ id: user.profile.id }); user.profile = updatedProfile; return { user, }; } }
可选调整说明
如果业务允许用户将字段清空为空字符串/null,可以保留当前过滤逻辑即可支持用户主动清空字段的需求;如果仅需要更新非空有效值,可以将过滤条件调整为:
Object.entries(updatableFields).filter(([_, value]) => value !== undefined && value !== null && value !== '')
内容的提问来源于stack exchange,提问作者crispengari
相关产品推荐
相关产品推荐

