如何使用Nestjs和TypeOrm定义多对多列?

时间:2020-07-24 17:35:19

标签: nestjs typeorm

我是nestjs / typeorm的新手,所以请您道歉和谅解。

我建立了多对多关系;我的表格是使用正确的列自动创建的。

我的位置可以有很多用户,一个用户可以有很多位置。

我的路线如下:

http://localhost:3000/locations/:location-id/users

我的location.entity.ts看起来像这样:

@ManyToMany(type => User, user => user.locations, { eager: true })
  @JoinTable()
  users: User[];

我的user.entity.ts看起来像这样:

@ManyToMany(type => Location, location => location.users, { eager: false })
  locations: Location[];

location_users_user表通过以下列生成:

locationId | userId

到目前为止,一切看起来都很不错!当我使用邮递员向我的路线发送GET请求时,在控制台中看到此错误:

column location_users_user.locationid does not exist 

当我的列名为locationid时,我看到的是locationId。我是否需要设置列名的大小写?

我还通过this SO thread进行了工作,以在JoinTable装饰器中设置其他参数。

这让我有了:

// location.entitiy.ts
@ManyToMany(type => User, user => user.locations, { eager: true })
  @JoinTable({
    name: 'location_user',
    joinColumn: {
      name: 'locationId',
      referencedColumnName: 'id',
    },
    inverseJoinColumn: {
      name: 'userId',
      referencedColumnName: 'id',
    },
  })
  users: User[];

但是,我仍然遇到此错误:

column location_users_user.locationid does not exist 

我认为我没有设置正确的Join或其他内容。我的位置实体上只有那个装饰器。

谢谢您的任何建议!

编辑

我更新了user.repository.ts文件,如下所示:

async getLocationUsers(locationId: number): Promise<User[]> {
    const query = this.createQueryBuilder('location_user')
      .where('location_user.locationId = :locationId', { locationId });

该错误仍然认为我正在寻找locationid列。我将其更改为foo,只是为了查看我是否在正确的位置,而且我确实在。我不确定为什么缺少locationId的情况。

EDIT2

我发现这可能是Postgres的事情?使用双引号,我现在在错误中看到正确的表/列名称:

const query = this.createQueryBuilder('location_user')
      .where('location_user."locationId" = :locationId', { locationId });

结果:column location_user.locationId does not exist 仍然很奇怪,因为该表确实存在,并且该列也存在。

修改

这是location.entity.ts文件:

@PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToMany(type => User, user => user.locations, { eager: true })
  @JoinTable()
  users: User[];

这是user.entity.ts文件:

 @PrimaryGeneratedColumn()
 id: number;

 @Column()
 email: string;

 @ManyToMany(type => Location, location => location.users, { eager: false })
 locations: Location[];

当我到达特定位置时,我可以看到用户的关系,所以我知道这是正常的。我试图获取属于该位置的所有用户;这是我的user.repository.ts文件的样子:

async getLocationUsers(locationId: number): Promise<User[]> {
    const query = this.createQueryBuilder('user')
      .where('location_users_user."locationId" = :locationId', { locationId });
});

    try {
      return await query.getMany();
    } catch (e) {
      console.log('error: ', e);
    }
  }

1 个答案:

答案 0 :(得分:2)

我刚刚使用@ManyToMany检查了一些自己的代码,我发现的仅有两个区别如下:

第一佳选

在我的存储库中,当使用连接的列调用TypeOrm的createQueryBuilder方法时,有两点不同:

  1. 我使用leftJoin(取决于您的用例逻辑和数据库设计,可能是另一个)来检索链接表
  2. 要过滤结果的FK字段上没有双引号

您在getLocationUsers中的user.repository.ts方法的代码将导致以下结果:

async getLocationUsers(locationId: number): Promise<User[]> {
    const query = this.createQueryBuilder('user')
      .leftJoin('user.locations', 'location')
      .where('location.id = :locationId', { locationId });
});

    try {
      return await query.getMany();
    } catch (e) {
      console.log('error: ', e);
    }
  }

第二个以防万一第一个无法解决您的问题

@ManyToMany(type => Location, location => location.users, { eager: false })

我正在使用

@ManyToMany(() => Location, (location) => location.users, { eager: false })

这种区别(不要使用type =>而是() =>)会有所改变吗?老实说,我不这么认为,可能是一些语法上的糖(或者不是-待确认,这只是假设)

希望有帮助,让我知道:)