为何在NestJS中保存关联实体时需重复设置category字段?
问题解答:为何保存图书时需重新设置category字段
核心原因:DTO与实体的category字段类型完全不同
你的CreateBookDto里的category是字符串类型(接收用户传入的分类名称),但Book实体中的category字段是Category实体对象类型——TypeORM需要实体对象来处理数据库的外键关联,直接传字符串根本无法被识别为有效的关联关系。
为什么不会冲突?对象属性的覆盖规则
在JavaScript/TypeScript中,对象展开后如果有重复属性,后面的属性会覆盖前面的。你这里的代码:
{ ...createBookDto, // 这里的category是字符串 category: category, // 这里的category是Category实体对象,会覆盖前面的字符串 createdBy: user.sub, }
最终传给save方法的对象里,category是正确的实体对象,不会有冲突。
这么做的关键作用
- 验证分类合法性:
validateCategory函数会检查传入的分类名称是否存在于数据库中,如果不存在直接抛出异常,避免创建关联无效分类的图书。 - 满足TypeORM关联要求:TypeORM处理
@ManyToOne关联时,必须传入对应的实体对象(或包含主键的对象),这样它才能自动将该分类的id写入图书表的外键字段(比如categoryId),完成数据库层面的关联。
实际场景示例
假设用户传入的createBookDto是:
{ "title": "三体", "author": "刘慈欣", "category": "科幻" }
validateCategory会从数据库找到对应的Category实体:
{ id: 1, name: "科幻", description: "包含科幻元素的文学作品" }
最终传给save的对象是:
{ title: "三体", author: "刘慈欣", category: { id:1, name:"科幻", ... }, // 实体对象 createdBy: 123 // 当前用户ID }
TypeORM会自动把category.id(1)写入图书表的外键列,完成关联。
内容的提问来源于stack exchange,提问作者Jorge Calo
相关产品推荐
相关产品推荐

