TypeORM многие ко многим получают все отношения - PullRequest
1 голос
/ 20 июня 2020

Итак, моя проблема может быть немного сложнее, чем следует из названия - я не знаю, как описать это кратким заголовком.

Предположим, у меня есть две сущности с отношением «многие ко многим» между ними Question и Category. В базе данных отношения определены в таблице соединений. Question - это «сторона-владелец» в этих отношениях - точно так же, как в этом примере: https://typeorm.io/# / many-to-many-Relations / what-are-many-to-many-Relations

Теперь приходит часть, с которой у меня возникают трудности: я всегда хочу вернуть отношения категорий в вопросе, если он есть. Если я делаю это через репозиторий, я могу очень легко сделать это примерно так:

let question = questionRepository.find(id, {relation: ['categories']};

он вернет вопрос с всеми его категориями.

Это становится труднее, когда я хочу сделать это с помощью QueryBuilder. Причина в том, что я пытаюсь составить список вопросов с всеми их категориями на основе массива категорий. Итак, представьте себе следующие данные:

Вопросы:

  1. ВопросA
  2. ВопросB
  3. Вопрос C

Категории:

  1. Категория1
  2. Категория2

Отношения:

  1. ВопросA - Категория1
  2. ВопросA - Категория2
  3. ВопросB - Категория1

Опять же, я хочу получить вопросы с всеми их категориями. И я пытаюсь сделать это с помощью QueryBuilder, используя массив CategoryID в предложении where. Это мой текущий конструктор запросов:

let count = categoryIds.length;
let queryBuilder = questionRepository.createQueryBuilder('q')
    .leftJoin('q.categories', category)
    .where('category.id IN (:categoryIds), {categoryIds})
    .groupBy('q.id)
    .having(COUNT(DISTINCT category.id) = :count, {count})
    .getMany();

Что касается получения всех вопросов, содержащих указанные категории, это работает нормально. Проблема здесь в том, что я хочу вернуть все категории для найденных вопросов.

Итак, представьте, что если categoryIds будет содержать только Category1, он вернет и QuestionA, и QuestionB. Однако он не вернет все их категории.

Даже если бы я изменил .leftJoin('q.categories', category) на .leftJoinAndSelect('q.categories', category), он вернул бы только Category1 в массиве categories для обоих вопросов.

Я не смог понять этот, так что любая помощь будет принята с благодарностью! Спасибо.

1 Ответ

0 голосов
/ 30 июня 2020

Все зависит от того, чего вы хотите достичь. TypeORM предоставляет вам множество возможностей. Иногда достаточно использовать декораторы в определении сущности.

let results = questionRepository.createQueryBuilder('q')
    .leftJoin('q.categories', 'cat', 'cat.id IN(:...categoryIds)', {categoryIds})
    .getMany();

В других случаях необходимо вручную создать предложение ON.

let results = questionRepository.createQueryBuilder('q')
    .innerJoin('relations', 'r', 'q.id = r.queryId')
    .innerJoinAndMapMany('q.categories', 'categories', 'c', 
        'c.id = r.categoryId AND c.id IN(:...categoryIds)', {categoryIds})
    .getMany();
   
...