我有三个实体 TestUser 、 TestProfile 和 TestPhoto,其中 TestUser 与 TestProfile 具有一对一关系,TestProfiles 与 TestPhoto 具有一对一关系,最后 TestPhoto 与 User 具有多对一关系,该关系可能尚未创建
我在定义我的实体时使用级联,我希望在我的 UserService 中通过一次调用来创建它们,但面临这个循环依赖:“TestPhoto”错误并且从那时起没有任何进展,我认为它可能不应该做什么在现实生活中,但除此之外,还有任何可能的黑客攻击或者根本不可能吗?
@Entity()
@Unique(["name"])
export class TestUser {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => TestProfile,{
cascade:true,
nullable:true
})
@JoinColumn()
profile: TestProfile;
@Column({nullable:true})
profileId: number
@OneToMany(() => TestPhoto, photo => photo.user)
photos: TestPhoto[];
}
@Entity()
export class TestProfile {
@PrimaryGeneratedColumn()
id: number;
@Column()
gender: string;
@OneToOne(type=>TestPhoto,{
cascade:true,
nullable:true
})
@JoinColumn()
photo: TestPhoto;
@Column({nullable:true})
photoId: number
}
@Entity()
export class TestPhoto {
@PrimaryGeneratedColumn()
id: number;
@Column()
url: string;
@ManyToOne(() => TestUser, user => user.photos,{
cascade:true,
nullable:true
})
user: TestUser;
@Column({nullable:true})
userId: number;
}
在我的 UserService 中抽象了如下调用
const user = new TestUser();
const profile1 = new TestProfile();
const photo1 = new TestPhoto();
photo1.user = user;
profile1.photo = photo1;
user.profile = profile1
await connection.manager.save(user);
我用 typeorm 解决了这个问题 Relation 在这里解释 tyopeorm 实体循环依赖
在编写代码之前,请先了解循环依赖的概念; 链接。在您的情况下可能存在循环依赖,但在现实生活场景中可能不会。你所要做的就是让你的实体/模态在双方都成为forwardRef。然后使用另一个服务的构造函数内的
@Inject(forwardRef(() => YourService))
使服务能够注入到其他服务中。如果您不明白,我将发布一个完整的示例,说明循环依赖在您的案例和现实生活场景中如何工作。
当存在循环依赖问题时,我使用通用导入文件:
// common.ts
// also it's important to keep order, parent first and then...
export * from './parent.entity';
export * from './child1.entity';
export * from './child2.entity';
// parent.entity.ts ------------------------------------
import { Child1Entity, Child2Entity } from './common.ts'
export class ParentEntity {
@OneToOne(() => Child1Entity, child => child.parent)
public child1: Child1Entity[];
@OneToOne(() => Child2Entity, child => child.parent)
public child2: Child2Entity[];
}
// child1.entity.ts ----------------------
import { ParentEntity } from './common.ts'
export class Child1Entity extends Parent {
@OneToOne(() => ParentEntity, parent => parent.child1)
@JoinColumn()
public parent: ParentEntity;
}
// child2.entity.ts ----------------------
import { ParentEntity } from './common.ts'
export class Child2Entity extends Parent {
@OneToOne(() => ParentEntity, parent => parent.child2)
@JoinColumn()
public parent: ParentEntity;
}
这个模式可以帮助你解决各种循环依赖问题
在 Typeorm 中,关系装饰器(@OneToMany、@ManyToOne、@OneToOne 和 ManyToMany)接受以下参数:
export declare function OneToMany<T>(typeFunctionOrTarget: string | ((type?: any) => ObjectType<T>), inverseSide: string | ((object: T) => any), options?: RelationOptions): PropertyDecorator;
如您所见,您可以提供 typeFunctionOrTarget (第一个参数)类型作为字符串,它可以防止 Typeorm 循环依赖错误。 就我而言,以下方法解决了循环依赖问题:
@OneToMany(
'CollectionPhase',
(collectionPhase: CollectionPhase) => collectionPhase.collectionNo,
)
phases?: Relation<CollectionPhase[]>;