Можно ли использовать подзапрос в leftJoinAndSelect в TypeORM - PullRequest
0 голосов
/ 17 апреля 2020

Итак, у меня есть проект в гнезде js и использующий TypeORM. И моя ситуация такова, что у меня есть пользователь, который имеет отношение «один к маю» с UserSubscrption. По умолчанию в поисковом запросе добавлены все подписки на пользователя, как и должно быть. Так что теперь я хочу найти одну указанную c подписку, например, последнюю добавленную. Поэтому я строю этот запрос:

    const query = this.createQueryBuilder("user")
    .leftJoinAndSelect("user.settings", "settings")
    .leftJoinAndSelect( 
      subQuery => {
          return subQuery
              .select()
              .from(UserSubscription, "subscription")
              .where("subscription.userId = :id AND subscription.isConfirmed = :isConfirmed", { id, isConfirmed: true })
              .orderBy('"createdDate"', 'DESC')
              .limit(1);
      }, 'subscription', '"subscription"."userId" = "user"."id"')
    .where('user.id = :id', { id });
    const result = await query.getOne(); // await query.execute()

Сначала я пытаюсь просто выполнить запрос, и он работает нормально, но все данные не структурированы

[
  {
    user_id: 1,
    user_username: 'name',
    ...
    settings_id: 1,
    settings_ifOnline: true,
    ...
    subscriptions_id: 1,
    subscriptions_subscriptionId: 1,
    ...
  }
]

Так что это не хорошо.

Затем я пытаюсь выполнить query.getOne (), но он не будет работать так, как я хочу, он потерял все данные подписки

User {
  id: 1,
  username: 'name',
  ...
  settings: UserNotificationSettings {
    id: 1,
    ifOnline: true,
    ...
  }
}

Кроме того, я попытался добавить подписку виртуального поля для объекта пользователя и попытаться использовать leftJoinAndMapOne :

    ...
    .leftJoinAndSelect("user.settings", "settings")
    .leftJoinAndMapOne("user.subscription", 
      subQuery => {
          return subQuery
              .select()
              .from(UserSubscription, "subscription")
              .where("subscription.userId = :id AND subscription.isConfirmed = :isConfirmed", { id, isConfirmed: true })
              .orderBy('"createdDate"', 'DESC')
              .limit(1);
      }, 'subscription', '"subscription"."userId" = "user"."id"')
    ...

Но без удачи. В документации сказано, что «подзапросы поддерживаются в выражениях FROM, WHERE и JOIN». но пример не приводится. Итак, я понятия не имею, как справиться с этим, я верю довольно простой запрос с TypeORM. Какие-либо предложения? Я вроде застрял с этим. Может быть, есть какой-то лучший способ, чем запросы builddibg? Спасибо.

User.entity

 export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;
  ...

  // subscription: UserSubscription;

  @OneToMany(type => UserSubscription, subscriptions => subscriptions.user, { cascade:true })
  subscriptions: UserSubscription[];

  @OneToOne(type => UserNotificationSettings, settings => settings.user, { cascade:true })
  settings: UserNotificationSettings;
}

UserSubscription.entity

export class UserSubscription extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @OneToOne(type => Subscription)
  @JoinColumn()
  subscription: Subscription

  @Column()
  subscriptionId: number

  @ManyToOne(type => User, user => user.subscriptions)
  user: User

  @Column({type: 'integer'})
  userId: number

  @Column({ type: 'boolean', default: false })
  isConfirmed: boolean

  ...
}
...