【问题标题】:Doctrine 2 WHERE IN clause using a collection of entitiesDoctrine 2 WHERE IN 子句使用实体集合
【发布时间】:2013-09-03 09:02:57
【问题描述】:

我正在尝试在 Doctrine 2 中构建一个查询,以查找与任何给定 VacancyWorkingHours 实体相关的所有 Vacancy 实体。

Vacancy 实体如下所示:

/**
 * Vacancy
 *
 * @ORM\Table(name="vacancy")
 * @ORM\Entity(repositoryClass="JaikDean\CareersBundle\Entity\VacancyRepository")
 */
class Vacancy
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var VacancyWorkingHours
     *
     * @ORM\ManyToOne(targetEntity="VacancyWorkingHours", inversedBy="vacancies")
     * @ORM\JoinColumn(name="vacancy_working_hours_id", referencedColumnName="id")
     **/
    private $workingHours;

    /* Other fields and methods are inconsequential */
}

我的查询目前如下所示,但由于 where 子句,没有返回任何结果。在此示例中,$workingHours 是一个 Doctrine\Common\Collections\ArrayCollection 实例,其中包含许多 VacancyWorkingHours 实体

$q = $this->createQueryBuilder('v')
    ->select('v')
    ->andWhere('v.workingHours IN (:workingHours)')
    ->setParameter('workingHours', $workingHours->toArray());
;

【问题讨论】:

    标签: php symfony orm doctrine-orm doctrine


    【解决方案1】:

    我建议以这种方式使用 DQL:

    $qb = $this->createQueryBuilder('v')
        ->andWhere($qb->expr()->in('v.workingHours', $ids));
    ;
    

    让 Doctrine 为您处理表达和引用工作。

    【讨论】:

      【解决方案2】:

      我提出的一个pull request已经合并到Doctrine ORM 2.5中,所以你现在可以简单地这样做:

      $q = $this->createQueryBuilder('v')
          ->select('v')
          ->andWhere('v.workingHours IN (:workingHours)')
          ->setParameter('workingHours', $workingHours);
      ;
      

      Doctrine 的最新版本现在允许集合参数,并将自动使用每个集合条目的主键。

      【讨论】:

        【解决方案3】:

        尝试将 ID 设置为参数

        $ids = array();
        foreach($workingHours as $w) {
            $ids[] = $w->getId();
        }
        

        然后

        $q = $this->createQueryBuilder('v')
            ->select('v')
            ->andWhere('v.workingHours IN (:workingHours)')
            ->setParameter('workingHours', $ids);
        ;
        

        【讨论】:

        • 谢谢,这行得通。必须引用关键字段而不是让 Doctrine 处理它似乎很奇怪/错误。
        • @JaikDean 是的,这确实很奇怪,这就是为什么我提出了一个补丁来增强它,以便它与实体而不是 id 一起工作。它已被合并并将在 Doctrine 2.5 中可用:github.com/doctrine/doctrine2/pull/590
        • @MichaëlPerrin 好消息!
        【解决方案4】:

        我认为 DQL 会更好地解决这个问题。

        $em = $this->getDoctrine()->getEntityManager();
        $query = $em->createQuery(
            'SELECT v
            FROM YourAppYourBundle:YourEntity v // exemple AcmeexampleBundle:YourEntity
            WHERE v.workingHours IN :workingHours'
        )->setParameter('workingHours', $workingHours->toArray());
        
        $vacancies = $query->getResult();
        

        【讨论】:

        • 谢谢,我可能最终会走那条路。特定的 WHERE IN 子句实际上是基于各种其他条件构建的更大查询的一部分,因此从组织的角度来看,使用查询构建器更容易。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-21
        • 2021-01-28
        • 2011-10-02
        相关资源
        最近更新 更多