我有一个Project
具有非自动生成的ID字段和后继字段的实体。此后继者是接下来的项目。但是也许没有后续的项目,所以它可能为空。
@Entity()
export class Project extends BaseEntity {
@PrimaryColumn({ unique: true })
public id: string;
@OneToMany(() => Project, project => project.id, { nullable: true })
public successorId?: string;
}
通过创建新项目时
public createProject(id: string, successorId?: string): Promise<Project> {
const project: Project = new Project();
project.id = id;
project.successorId = successorId;
return project.save();
}
我有很多情况要照顾。
传递已经存在的ID:
这不会引发错误。它只是覆盖现有实体。
传递undefined
给successorId
:
该代码然后可以正常工作,但不会successorId
在null
那时创建列。该列在数据库中根本不存在。
为id
和传递相同的ID successorId
(应该可以):
TypeORM引发错误
TypeError:无法读取未定义的属性“ joinColumns”
传入successorId
另一个现有项目:
我收到与上述相同的错误
传入successorId
不存在的项目:
我收到与上述相同的错误
那么我该如何解决呢?我认为我的实体设计似乎是错误的。基本上应该是
如果有人可以帮忙,那将会很棒!
更新资料
我也试过了
@OneToMany(() => Project, project => project.successorId, { nullable: true })
@Column()
public successorId?: string;
但是每当我想调用该createProject
方法时,都会出现此错误
QueryFailedError:“ successorId”列中的空值违反了非空约束
和这个
@OneToMany(() => Project, project => project.successorId, { nullable: true })
public successorId?: string;
但是然后我得到这个错误
TypeError:relatedEntities.forEach不是一个函数
请尝试此解决方案
@Entity()
export class Project extends BaseEntity {
@PrimaryColumn({ unique: true })
public id: string
@Column({ nullable: true })
public successorId?: string
@ManyToOne(() => Project, project => project.id)
@JoinColumn({ name: "successorId" })
public successor?: Project
}
public successor?: Project
-属性用于在实体之间建立关系(在这种情况下,相同的实体)。必须将相关实体指定为属性类型,因为TypeORM使用此类型来确定目标实体并建立关系元数据。您可以在此处阅读有关TypeORM关系的更多信息
public successorId?: string
-属性只是一个“提取的”连接列。使用ManyToOne
关系时,TypeORM会在数据库中自动创建一个名为propertyName
+ 的列referencedColumnName
(successorId
在这种情况下)。但是您不能在代码中使用此列,因为它仅在表中定义,而不在类中定义。并且,如果您需要在类中定义此列(以进行进一步保存或显示),则可以创建一个属性并用@Column
装饰器对其进行标记。属性名称必须与表中的连接列名称相同。在这里更详细地描述
创建具有相同ID的实体只会覆盖现有的实体
这是预期的行为。当您尝试使用现有ID保存实体时,TypeORM会将其识别为更新,而不是创建
我测试了您的解决方案,我认为这似乎可行。您介意解释为什么需要两个字段吗?它知道如何通过字符串将该字段映射到变量吗?
唯一仍然失败的情况是第一部分。创建具有相同ID的实体只会覆盖现有的..
是的,我可以使用此示例存储库来重现它:) github.com/mhcomp/…
是的,在TypeORM中
@OneToMany
是的反面,@ManyToOne
没有则不能存在@ManyToOne
。也@OneToMany
并非必需的,在这种情况下中省略。例如,如果您需要“在后继项目之前跟随的项目”,或者换句话说,“在其中将该项目指定为后继项目的项目”,则需要将其OneToMany
用作反面。看起来像@OneToMany(() => Project, project => project.successor) public projects: Project[]
顺便说一句,我不知道您对继任者的要求。如果可以在多个项目中指定一个继任者,那么
@ManyToOne
正确的方法是。否则,如果一个继任者只能跟随一个项目,则应@OneToOne
改为使用关系。