Doctrine2 LEFT JOIN с двумя условиями

Я пытаюсь найти «Продукт» по идентификатору и оставить все его «Фото» при двух условиях: локаль И активное состояние.

Вот мой QueryBuilder:

$queryBuilder = $this->createQueryBuilder('p')
            ->select('p, photos, photoTranslation')
            ->leftJoin('p.photos', 'photos')
            ->leftJoin('photos.translations', 'photoTranslation')
            ->where('p.id = :id')
            ->andWhere('(photoTranslation.locale = :locale OR photoTranslation.locale IS NULL)')
            ->andWhere('(photoTranslation.active = :active OR photoTranslation.active IS NULL)')
            ->setParameters(array(
                'id' => $id
                'locale' => $this->getLocale(),
                'active' => true
             ));

Он отлично работает, когда нет фотографий или когда есть АКТИВНЫЕ фотографии, но не когда есть неактивная фотография, потому что она не соответствует ни одному из двух условий.

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

$queryBuilder = $this->createQueryBuilder('p')
            ->select('p, photos, photoTranslation')
            ->leftJoin('p.photos', 'photos')
            ->leftJoin('photos.translations', 'photoTranslation')
            ->where('p.id = :id')
            ->andWhere('(photoTranslation.locale = :locale OR photoTranslation.locale IS NULL)')
            ->setParameters(array(
                'id' => $id
                'locale' => $this->getLocale()
             ));

На данный момент я зацикливаюсь на этих результатах и ​​отключаю все неактивные фотографии ... но мне нужен чистый способ сделать это в QueryBuilder.

Я также попытался поставить условия в предложении LEFT JOIN:

->leftJoin('photo.translations', 'phototTranslation', Doctrine\ORM\Query\Expr\JOIN::WITH, 'photoTranslation.locale = :locale AND photoTranslation.active = :active')

Но он всегда возвращает фото, даже если оно неактивно.


person Tiois    schedule 04.04.2013    source источник


Ответы (1)


Решением этой проблемы может быть:

$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
    ->select('p', 'pp')
    ->from('Product', 'p')
    ->leftJoin('p.photos', 'pp')
    ->leftJoin('pp.translations', 'ppt', Doctrine\ORM\Query\Expr\Join::WITH, $qb->expr()->andX(
        $qb->expr()->eq('ppt.locale', ':locale'),
        $qb->expr()->eq('ppt.active', ':active')
    ))
    ->where('p.id', ':productId')
    ->setParameters(
        array(
            'productId', $productId,
            'active', $active,
            'locale', $locale
        )
    );

    $query = $qb->getQuery();
    return $query->getResult(); // or ->getSingleResult();

ПРИМЕЧАНИЕ: этот пример — способ сделать это в репозитории сущностей Symfony2 (2.3)

person adridev    schedule 11.02.2014
comment
Я везде искал пример того, как добавить условия и IN внутри запроса на соединение. Это «andX» спасло мой день! - person M. Marc; 03.03.2017
comment
Спасибо большое ! - person Yohann Daniel Carter; 25.10.2019