如何使用 NestJS 和 TypeORM 定义多对多列?

How can I define many to many columns with NestJS and TypeORM?

我是 NestJS/TypeORM 的新手,所以请原谅我。

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

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

我的路线是这样的:

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 table 正在生成这些列:

locationId | userId

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

column location_users_user.locationid does not exist 

我看到 locationid 是它要查找的内容,而我的列名称是 locationId。有什么地方需要设置列名的大小写吗?

我还通过 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 的东西?使用双引号,我现在在错误中看到了正确的 table/column 名称:

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

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

编辑

这是 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);
    }
  }

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

第一个最佳选择

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

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

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

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 =>() =>)会改变什么吗?老实说我不这么认为,可能是一些语法糖(或者不是 - 待确认,这只是假设)

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