【问题标题】:Doctrine2 filter results by many to many relationshipDoctrine2 按多对多关系过滤结果
【发布时间】:2016-04-06 14:35:08
【问题描述】:

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

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/>";
    }
}

用户实体与实体 AdditionalServices 具有 Many2Many 关系。我需要过滤掉用户,如果他们提供额外的服务,例如 width id 26 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 会整理其他所有内容,那就太好了。但我会感谢任何可行的解决方案。

【问题讨论】:

    标签: mysql symfony orm doctrine-orm


    【解决方案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');
    

    如您所见,您甚至不必加入表,除非您实际上还想获取其他服务。

    【讨论】:

    • 其实你应该提供带参数的值。这有效: $qb->where($qb->expr()->isMemberOf(':service', 'c.additionalServices')) ->setParameter('service', $this->additionalServices);非常感谢!
    猜你喜欢
    • 2019-10-14
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2011-04-01
    • 1970-01-01
    相关资源
    最近更新 更多