2013-03-15 3 views
1

Short and Simple: время от времени мы отправляем подарки некоторым из наших пользователей. У меня есть таблица user и таблица gift со многими отношениями ко многим. Я хочу получить всех пользователей, которые НЕ получили подарок.Doctrine2 simple where clause issue

Следующий запрос, однако, возвращает мне всех пользователей и подарки, которые они получили, с исключительным подарком.

$qb = $this->_em->createQueryBuilder(); 
$qb->select('u, g') 
     ->from('Application\Entity\User', 'u') 
     ->leftJoin('u.gifts', 'g') 
     ->where('g.id != = :giftId') 
     ->setParameter('giftId', 2); 

Если пользователь получил конкретный подарок, я хочу исключить этого пользователя из набора результатов. Возможно ли это с Doctrine2?

ответ

0

Сначала необходимо выбрать всех пользователей, а затем исключить тех, кто был ваш подарок уже:

SELECT 
    u 
FROM 
    Application\Entity\User u 
WHERE 
    u.id NOT IN(
     SELECT 
      u2.id 
     FROM 
      Application\Entity\User u2 
     JOIN 
      u2.gifts g 
     WHERE 
      g.id = :giftId 
    ) 

В QueryBuilderAPI, это выглядит следующим образом:

$qb1 = $em->createQueryBuilder(); 
$qb2 = $em->createQueryBuilder(); 

$qb2 
    ->select('u2') 
    ->from('Application\Entity\User', 'u2') 
    ->join('u2.gifts', 'g') 
    ->andWhere($qb2->expr()->eq('g.id', ':giftId'); 

$users = $qb1 
    ->select('u') 
    ->from('Application\Entity\User', 'u') 
    ->andWhere($qb1->expr->in($qb2->getDQL()) 
    ->setParameter('giftId', $giftId) 
    ->getQuery() 
    ->getResult(); 

Кроме того, я не лично думаю, что QueryBuilder подходит для этого случая использования, если у вас нет динамического DQL. Как вы можете видеть, запрос становится довольно сложным, и в какой-то момент вы даже возвращаетесь к QueryBuilder#getDQL, который строит строку DQL и делает невозможным повторное использование $qb2. Plain DQL работает просто отлично.