Doctrine 2 WHERE IN 子句使用实体集合
Posted
技术标签:
【中文标题】Doctrine 2 WHERE IN 子句使用实体集合【英文标题】:Doctrine 2 WHERE IN clause using a collection of entities 【发布时间】: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());
;
【问题讨论】:
【参考方案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 子句实际上是基于各种其他条件构建的更大查询的一部分,因此从组织的角度来看,使用查询构建器更容易。以上是关于Doctrine 2 WHERE IN 子句使用实体集合的主要内容,如果未能解决你的问题,请参考以下文章
使用 PHP Doctrine ORM 的复杂 WHERE 子句
有人可以建议一种使用带有多个“where”子句的 Doctrine (QueryBuilder) 进行此查询的方法吗?