Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
772 views
in Technique[技术] by (71.8m points)

mysql - Doctrine2 LEFT JOIN with 2 conditions

I'm trying to find a 'Product' by ID, and to left join all it's 'Photo' on two conditions: the locale AND the active state.

Here's my 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
             ));

It works fine when there are no Photos or when there are ACTIVE photos, but not when there's an inactive Photo because it doesn't match one of the two conditions.

If I use only one condition, for instance only the locale part, it works fine :

$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()
             ));

For now, I loop on theses results and unset all inactive Photos... but I'd like a clean way to do in the QueryBuilder.

I also tried to put the conditions on the LEFT JOIN clause :

->leftJoin('photo.translations', 'phototTranslation', DoctrineORMQueryExprJOIN::WITH, 'photoTranslation.locale = :locale AND photoTranslation.active = :active')

But it always returns the Photo, even if it's inactive.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For this problem a solution may be:

$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
    ->select('p', 'pp')
    ->from('Product', 'p')
    ->leftJoin('p.photos', 'pp')
    ->leftJoin('pp.translations', 'ppt', DoctrineORMQueryExprJoin::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();

NOTE: this example is the way to do it in Symfony2 (2.3) entity repository


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...