【问题标题】:How can I define many to many columns with NestJS and TypeORM?如何使用 NestJS 和 TypeORM 定义多对多列?
【发布时间】:2020-11-14 14:58:00
【问题描述】:

我是 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

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

column location_users_user.locationid does not exist 

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

我还通过this SO threadJoinTable 装饰器中设置了额外的参数。

剩下的就是这个:

// 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);
    }
  }

【问题讨论】:

  • 能否请您添加两个实体的完整代码?
  • 嗨@yash 我刚刚在底部更新了我的问题,以包括关系和我的存储库方法。谢谢!

标签: nestjs typeorm


【解决方案1】:

我刚刚使用@ManyToMany 检查了我自己的一些代码,我能发现的唯一两个不同之处如下:

第一最佳选择

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

  1. 我使用leftJoin(可能是另一个,具体取决于您的用例逻辑和数据库设计)来检索链接表
  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 =&gt;,而是使用() =&gt;)会改变什么吗?老实说,我不这么认为,可能是一些语法糖(或者不是——有待确认,这只是假设)

希望对你有帮助,告诉我:)

【讨论】:

  • 这真的很有趣。我必须使用双引号,否则我没有得到locationId 的正确大小写。看来这是我显然做得不对的部分:.leftJoin('user.locations', 'location')。非常感谢您的参与。它帮助我回到了正确的轨道!
猜你喜欢
  • 2020-09-03
  • 2021-04-23
  • 2020-08-29
  • 1970-01-01
  • 2022-01-02
  • 2020-09-01
  • 1970-01-01
  • 2021-10-17
  • 2022-01-17
相关资源
最近更新 更多