Предложение IN Doctrine Query Builder с несколькими значениями - PullRequest
2 голосов
/ 04 октября 2019

У меня есть сущность User, которая имеет отношение ManyToMany с companyType:

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\CompanyType")
 * @ORM\OrderBy({"name" = "ASC"})
 * @ORM\JoinColumn(nullable=true)
 */
private $companyTypes;

И сущность Company, которая может иметь 0 или несколько типов:

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\CompanyType", inversedBy="companies")
 * @ORM\OrderBy({"name" = "ASC"})
 * @ORM\JoinColumn(nullable=true)
 */
private $companyTypes;

Это создает user_companyTypeтаблицы в моей базе данных.

Я хочу построить с Doctrine queryBuilder запрос, который возвращает, если хотя бы один элемент в u.companyTypes находится в c.companyTypes.

Я не могу найти как.

Вот что я пробовал:

$userCompanyTypes = array();
foreach ($user->getCompanyTypes() as $companyType) {
    $userCompanyTypes[] = $companyType;
}

$qb = $this->_em->createQueryBuilder('i')
->from(Invoice::class, 'i')
->leftJoin('i.account', 'a')
->leftJoin('i.company', 'c')
->leftJoin('c.companyTypes', 'ct')
->leftJoin('a.users', 'u')
->andWhere("c.companyTypes IN (:userCompanyTypes)") // ... search if there's a match 
->setParameter("userCompanyTypes", $userCompanyTypes);

return $qb->getQuery()->getResult();

Короче говоря:

  • Учетная запись содержит несколько пользователей

  • Счет всегда связан с учетной записью И компанией

  • CompanyType - это объект, а не строка

  • Я хочу получить счета, связанные с компаниями, на которые имеет право пользователь (= у пользователя есть тип компании, который есть у самой компании)

Есть ли что-то еще, что я могу использовать сконструктор запросов, чтобы сделать это?

1 Ответ

2 голосов
/ 04 октября 2019

Обычно я не люблю отвечать на подобные вопросы, не настроив тестовый пример. Ваше сообщение об ошибке немного странно, но я попробую. Я знаю, что предложение IN будет работать с отдельными идентификаторами. Так что, может быть:

$userCompanyTypeIds = array();
foreach ($user->getCompanyTypes() as $companyType) {
    $userCompanyTypeIds[] = $companyType->getId();
}
$qb = $this->_em->createQueryBuilder('i')
->select('count(DISTINCT i.id)')
->from(Invoice::class, 'i')
->leftJoin('i.account', 'a')
->leftJoin('i.company', 'c')
->leftJoin('c.companyTypes', 'ct')
->leftJoin('a.users', 'u')
->andWhere("ct.id IN (:userCompanyTypeIds)") // ... search if there's a match 
->setParameter("userCompanyTypeIds", $userCompanyTypeIds);

$count = $qb->getQuery()->getSingleScalarResult();

Должен хотя бы сделать шаг вперед. Обновлен ответ, показывающий, как получить общий счет. Никогда не был большим поклонником использования класса expr, хотя он довольно распространен.

...