使用 type-graphql typeorm 和 dataloader 处理一对多的最佳方法

Joe*_*sen 6 express graphql typeorm typegraphql dataloader

我试图找出使用 type-graphql 和 typeorm 和 postgresql db(使用 apollo 服务器和 express)处理一对多关系的最佳方法。我有一个与课程表具有一对多关系的用户表。我目前处理此问题的方法是使用 @RelationId 字段创建一列 userCourseIds,然后使用 @FieldResolver 和 dataloader 批量获取属于该用户的课程。我的问题是,对于 @RelationId 字段,无论我是否实际查询 userCourses,都会进行一个单独的查询来获取关系 ID。有没有办法解决这个问题,它不会进行额外的查询,或者有没有更好的方法来处理一对多关系?

关系的用户端:

@OneToMany(() => Course, (course) => course.creator, { cascade: true })
userCourses: Course[];
@RelationId((user: User) => user.userCourses)
userCourseIds: string;
Run Code Online (Sandbox Code Playgroud)

关系的课程方面:

@Field()
@Column()
creatorId: string;

@ManyToOne(() => User, (user) => user.userCourses)
creator: User;
Run Code Online (Sandbox Code Playgroud)

用户课程字段解析器:

@FieldResolver(() => [Course], { nullable: true })
async userCourses(@Root() user: User, @Ctx() { courseLoader }: MyContext) {
  const userCourses = await courseLoader.loadMany(user.userCourseIds);
  return userCourses;
}
Run Code Online (Sandbox Code Playgroud)

Kaz*_*ida 10

userCourses可以使用type-graphql-datalaoader@TypeormLoader提供的装饰器如下编写字段。

@ObjectType()
@Entity()
class User {
  ...

  @Field((type) => [Course])
  @OneToMany(() => Course, (course) => course.creator, { cascade: true })
  @TypeormLoader((course: Course) => course.creatorId, { selfKey: true })
  userCourses: Course[];
}

@ObjectType()
@Entity()
class Course {
  ...

  @ManyToOne(() => User, (user) => user.userCourses)
  creator: User;

  @RelationId((course: Course) => course.creator)
  creatorId: string;
}
Run Code Online (Sandbox Code Playgroud)

userCourseIds由于省略,将不再发出其他查询。虽然creatorIdwith@RelationId存在,但它不会发出额外的查询,因为实体有自己的值。

更新:2021 年 6 月

@TypeormLoader不再需要争论。因此,@RelationId如果愿意,可以完全省略。