如何在Typeorm多对多关系中选择特定列

时间:2020-04-09 03:42:33

标签: typeorm typeorm-activerecord

我与TYPEORM中的自定义联接表具有n:m关系。

Entity1

@Entity({ name: 'users' })
export class User extends BaseModel {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column({ type: 'varchar', length: 50 })
  @IsNotEmpty()
  username!: string;

  @Column({ unique: true, type: 'varchar', length: 50 })
  @IsEmail()
  @IsNotEmpty()
  email!: string;

  @CreateDateColumn({ type: 'timestamp' })
  createdAt!: Date;

  @UpdateDateColumn({ type: 'timestamp' })
  updatedAt!: Date;

  @DeleteDateColumn({ type: 'timestamp' })
  deletedAt!: Date;

  @OneToMany(
    (type) => UsersGameGroup,
    (userGameGroup) => userGameGroup.user,
    { cascade: true }
  )
  usersGameGroups!: UsersGameGroup[];
}

Entity2

@Entity({ name: 'game_groups' })
export class GameGroup extends BaseModel {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  title!: string;

  @OneToMany(
    (type) => UsersGameGroup,
    (userGameGroup) => userGameGroup.gameGroup,
    { cascade: true }
  )
  usersGameGroups!: UsersGameGroup[];
}

Entity3联接表

@Entity({ name: 'users_game_groups' })
export class UsersGameGroup extends BaseModel {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column({ type: 'int' })
  userId!: number;

  @Column({ type: 'int' })
  gameGroupId!: number;

  @ManyToOne(
    (type) => User,
    (user) => user.usersGameGroups,
    { onDelete: 'CASCADE' }
  )
  user!: User;

  @ManyToOne(
    (type) => GameGroup,
    (gameGroup) => gameGroup.usersGameGroups,
    { onDelete: 'CASCADE' }
  )
  gameGroup!: GameGroup;
}

我正在查询gameGroup以吸引用户。

const gg = await GameGroup.findOneOrFail(gameGroupID, {
        select: ['id', 'title'],
        relations: ['usersGameGroups', 'usersGameGroups.user']
      });
const { id, title, createdAt, updatedAt, usersGameGroups } = gg;

但是这里的问题是它将返回用户的所有列。我只想要username

返回样本:

{
  "meta": {},
  "payload": {
    "gameGroup": {
      "id": 2,
      "title": "game2",
      "users": {
        "id": 2,
        "title": "game2",
        "usersGameGroups": [
          {
            "id": 2,  <-this too I don't need this but whatever
            "userId": 1, <-this too I don't need this but whatever
            "gameGroupId": 2, <-this too I don't need this but whatever
            "createdAt": "2020-04-09T00:11:39.000Z", <-this too I don't need this but whatever
            "updatedAt": null, <-this too I don't need this but whatever
            "deletedAt": null, <-this too I don't need this but whatever
            "user": {
              "id": 1,
              "username": "new1",
              "email": "new1@gmail.com", <- I just need this
              "createdAt": "2020-04-09T00:09:45.000Z",
              "updatedAt": "2020-04-09T00:10:55.000Z",
              "deletedAt": null
            }
          },
          {
            "id": 3, <-this too I don't need this but whatever
            "userId": 2, <-this too I don't need this but whatever
            "gameGroupId": 2, <-this too I don't need this but whatever
            "createdAt": "2020-04-09T00:12:10.000Z", <-this too I don't need this but whatever
            "updatedAt": null, <-this too I don't need this but whatever
            "deletedAt": null, <-this too I don't need this but whatever
            "user": {
              "id": 2,
              "username": "new2", <- I just need this
              "email": "new2@gmail.com",
              "createdAt": "2020-04-09T00:09:51.000Z",
              "updatedAt": null,
              "deletedAt": null
            }
          }
        ]
      }
    }
  }
}

如果我这样查询它。我包含user及其用户名,例如user.username

relations: ['usersGameGroups', 'usersGameGroups.user', 'user', 'user.username']

我得到一个错误。

"Relation \"user\" was not found, please check if it is correct and really exist in your entity."

在原始SQL中,查询看起来像这样。

SELECT
    u.username
FROM 
    users u
JOIN 
    users_game_groups ugg
ON ugg.userId = u.id
JOIN 
    game_groups gg
ON gg.id = ugg.gameGroupId
WHERE gg.id = 2;

我期望这样的JSON响应。

"gameGroup": {
      "id": 2,
      "title": "game2",
      "users": {
        "id": 2,
        "title": "game2",
        "usersGameGroups": [
          {
            "user": {
              "username": "new1",
            }
          },
            "user": {
              "username": "new2",
            }
          }
        ]
      }
    }

谢谢!! <3

1 个答案:

答案 0 :(得分:0)

啊,终于经过反复试验,阅读了实际的代码库,并且完全不放弃,我终于得到了答案。

HiloSeries<Offset, DateTime>(
                enableTooltip: true,
                markerSettings: MarkerSettings(
                    borderWidth: 8,
                    width: 10,
                    shape: DataMarkerType.image,
                    borderColor: Colors.black,
                    isVisible: true,
                    color: Colors.black,
                    height: 10,
                    image: Image.asset('assets/images/logo.png').image),
                color: Colors.green,
                borderWidth: 2,
                xValueMapper: (Offset stonk, _) => DateTime(stonk.dx.toInt()),
                highValueMapper: (Offset stonk, _) => stonk.dx,
                lowValueMapper: (Offset stonk, _) => stonk.dy,
                dataSource: [Offset(1, 2), Offset(2, 1), Offset(3, 4)],
              )

但是我希望它使用活动记录。

类似:

const foo = await GameGroup.createQueryBuilder()
        .select(['gg.title', 'gg.id', 'ugg.id', 'u.username', 'u.email'])
        .from(GameGroup, 'gg')
        .innerJoin('gg.usersGameGroups', 'ugg')
        .innerJoin('ugg.user', 'u')
        .where({ id: gameGroupID })
        .getOne();

但是我不能从这里选择。我不能叹息const gg = await GameGroup.findOneOrFail(gameGroupID, { select: ['id', 'title', 'createdAt', 'updatedAt', 'usersGameGroups'], join: { alias: 'gg', innerJoinAndSelect: { ugg: 'gg.usersGameGroups', u: 'ugg.user' } } }); :(