不是在多对多关系中使用Doctrine QueryBuilder进行查询

时间:2015-06-23 16:46:37

标签: symfony doctrine many-to-many query-builder

在我的Symfony2项目中,我有两个实体“联系人”和“设置”,有多对多关系:

/**
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Settings", cascade={"persist"})
 * @ORM\JoinColumn(nullable=true)
 */
private $settings;

实体设置有一个属性“parametre”,这是一个简单的字符串。

现在我希望得到所有没有“参数”是“主题”的设置的联系人。

我可以在SQL中执行以下查询:

SELECT DISTINCT(c.id) FROM contact c WHERE c.id
NOT IN (SELECT cs.contact_id FROM contact_settings cs
INNER JOIN Settings s ON s.id = cs.settings_id
WHERE s.parametre = "THEMES")

但我无法弄清楚如何使用Doctrine的查询构建器来完成它。 这是我到目前为止所尝试的内容:

$query = $this->createQueryBuilder('c')
    ->join('c.settings', 's');

$qb2 = $qb;

$qb2->select('s2')
    ->from('AppBundle\Entity\Settings', 's')
    ->where('s2.parametre = :parametre');

$query->where(($qb->expr()->notIn('s', $qb2->getDQL())));
$query->setParameter('parametre', 'THEMES');
$result = $query->getQuery()->getResult();

这不会返回任何结果。

谢谢!

2 个答案:

答案 0 :(得分:7)

您可以尝试这样的事情:

$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
    ->select(['cs.id'])
    ->from('AcmeDemoBundle:Contact', 'cs')
    ->innerJoin('cs.settings', 's')
    ->where('s.parameter = :parameter')
    ->setParameter('parameter', 'THEMES')
    ->getQuery()
    ->getArrayResult()
;

$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
    ->select(['c'])
    ->from('AcmeDemoBundle:Contact', 'c')
    ->where($queryBuilder->expr()->notIn('c.id', ':subQuery'))
    ->setParameter('subQuery', $subQuery)
    ->getQuery()
;

$result = $query->getResult();

这只是你问题的一个例子。我无法提供完整的示例,因为我不了解您实体的结构......

答案 1 :(得分:0)

xurshid29接受的答案将使用2个查询。但是通过在“-> notIn()”函数中使用getDQL(),您可以在1个查询中做到这一点:

$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
    ->select('cs.id')
    ->from('AcmeDemoBundle:Contact', 'cs')
    ->innerJoin('cs.settings', 's')
    ->where('s.parameter = :parameter')
    ->setParameter('parameter', 'THEMES')
;

$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
    ->select('c')
    ->from('AcmeDemoBundle:Contact', 'c')
    ->where($queryBuilder->expr()->notIn('c.id', $subQuery->getDQL()))
    ->getQuery()
;

$result = $query->getResult();

警告!不要尝试将DQL设置为参数,这将导致字符串而不是真实的SQL语法。 所以这是错误的,将不起作用

// THIS IS WRONG
->where($queryBuilder->expr()->notIn('c.id', ':subQuery'))
->setParameter('subQuery', $subQuery->getDQL())