【问题标题】:fetch all nested resources by resource id on a many to many relationship在多对多关系中按资源 id 获取所有嵌套资源
【发布时间】:2020-02-08 15:35:46
【问题描述】:

我想用 TypeORM 创建一个 NestJs API,并有两个实体,usersgroups。一个用户可以加入多个群组,一个群组可以有多个用户。

我为用户创建了这些 ORM 模型

@Entity('User')
export class UserEntity {
  @PrimaryGeneratedColumn()
  id: number;

  // ...

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.users)
  @JoinTable()
  groups: GroupEntity[];
}

对于团体

@Entity('Group')
export class GroupEntity {
  @PrimaryGeneratedColumn()
  id: number;

  // ...

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.groups)
  @JoinTable()
  users: UserEntity[];
}

当调用路由GET localhost:3000/users/1/groups 时,我想返回用户所属的组数组。 UsersService 执行此操作

const groups: GroupEntity[] = await this.groupsRepository.find({
  where: { userId: 1 },
  relations: ['users'],
});

当调用路由GET localhost:3000/groups/1/users 时,我想返回该组持有的用户数组。 GroupsService 执行此操作

const users: UserEntity[] = await this.usersRepository.find({
  where: { groupId: 1 },
  relations: ['groups'],
});

不幸的是,两个端点都会返回每个嵌套的子资源。似乎where 子句被忽略了。数据库创建两个交叉表

但我希望只有一个交叉表,因为其中一个是多余的,不是吗?当然,这可能有技术原因。获取子资源的正确方法是什么?

【问题讨论】:

    标签: javascript node.js typescript nestjs typeorm


    【解决方案1】:

    第一个问题

    在 TypeORM 中,当您定义 @ManyToMany 关系时,您需要在关系的一侧(拥有)使用 @JoinTable

    所以这样一来,它只会创建一个交叉表。

    例子

    @Entity('User')
    export class UserEntity {
      @PrimaryGeneratedColumn()
      id: number;
    
      // ...
    
      @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.users)
      @JoinTable()
      groups: GroupEntity[];
    }
    
    @Entity('Group')
    export class GroupEntity {
      @PrimaryGeneratedColumn()
      id: number;
    
      // ...
    
      @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.groups)
      users: UserEntity[];
    }
    
    

    It will generate three tables users, groups, and user_groups_group

    第二个问题

    你可以使用这个查询

    user = await userRepo.find({
        relations: ['groups'],
        where: { id: user.id }
    });
    const groups = user.groups
    

    正如您的代码所暗示的,您正在使用 typeORM 的延迟加载,因此您可以这样做

    const user = await userRepo.find({
        where: { id: someId }
    });
    const groups = await note.groups
    

    【讨论】:

    • 感谢您的回复。因此,如果我说得对,我会从 GroupEntity 中删除 @JoinTable() 并进行此查询 hatebin.com/pfiqqysjzi 并对组服务执行相同的操作?
    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多