2013-03-15 72 views
1

簡單和簡單:我們不時向我們的一些用戶發送禮物。我有一個user表和一個gift表與多對多的關係。我想獲取所有未收到特定禮物的用戶。Doctrine2簡單的條款問題

但是,下列查詢會將所有用戶和他們收到的禮物返還給我,並排除特定禮物。

$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不可能再循環。 普通DQL在這裏工作得很好。