Doctrine2过滤结果由多对多关系组成

时间:2016-04-06 14:35:09

标签: mysql symfony orm doctrine-orm

我正在构建搜索。这是用于此目的的方法:

public function execute()
{
    $this->handleSearchQuery();

    $startDate = new \DateTime($this->date . ' ' . $this->time);

    $timeRequiredInterval = new \DateInterval("PT" . $this->hoursRequired * 60 . "M");

    $endDate = $startDate->add($timeRequiredInterval);

    $date = $startDate->format('Y-m-d');
    $startTime = $startDate->format('H:i');
    $endTime = $endDate->format('H:i');

    $repo = $this->em->getRepository('AppBundle:User');
    $qb = $repo->createQueryBuilder('c');

    $qb->select('c')
        ->innerJoin('c.workingTime', 'wt', Join::WITH, $qb->expr()->andX(
            $qb->expr()->eq('wt.day', ':day'),
            $qb->expr()->lte('wt.workTimeStarts', ':timeStart'),
            $qb->expr()->gte('wt.workTimeEnds', ':timeEnd')
        ))
        ->innerJoin('c.cityDistricts', 'cd', Join::WITH, 'cd.id = :district')
        ->setParameter('timeStart', $startTime)
        ->setParameter('timeEnd', $endTime)
        ->setParameter('day', $date)
        ->setParameter('district', $this->district);

    if ($this->additionalServices) {
        $qb->innerJoin('c.additionalServices', 'se');
        $qb->where('se.id = 26');
    }

    $query = $qb->getQuery();
    $result = $query->getResult();

    foreach ($result as $item) {
        echo $item->getFirstName() . "<br/>";
    }
}

用户实体与Entity AdditionalServices具有Many2Many关系。我需要过滤掉用户,如果他们提供其他服务,例如,宽度ID AND 27

if ($this->additionalServices) {
    $qb->innerJoin('c.additionalServices', 'se');
    $qb->where('se.id = 26');
}

如果我们只需要一个服务,但是这个服务不会产生预期结果,那么它是有效的:

if ($this->additionalServices) {
    $qb->innerJoin('c.additionalServices', 'se');
    $qb->where('se.id = 26');
    $qb->andWhere('se.id = 27');
}

那我怎么办呢?如果有可能只提供带有AdditionalService ID的数组,并且Doctrine会将其他所有内容排序,那就太好了。但我会很感激任何有效的解决方案。

1 个答案:

答案 0 :(得分:1)

Doctrine DQL提供了MEMBER OF规则,您应该将其用于此目的。所以而不是:

$qb->innerJoin('c.additionalServices', 'se');
$qb->where('se.id = 26');
$qb->andWhere('se.id = 27');

这足以写出:

$qb->where('26 MEMBER OF c.additionalServices');
$qb->andWhere('27 MEMBER OF c.additionalServices');

正如您所看到的,您甚至不必加入表格,除非您真的想要获取其他服务。