构建查询以选择没有相应N个实体的M个实体将使用以下查询返回错误:
return $this->getEntityManager()
->createQuery(
'SELECT p FROM VolVolBundle:Opportunity p '
. 'LEFT JOIN VolVolBundle:Volunteer v'
. 'WHERE v.id is null '
. 'ORDER BY p.organization ASC'
);
返回错误:
预期的Doctrine \ ORM \ Query \ Lexer :: T_WITH,得到'v'
然而,以下SQL语句返回非空结果集:
select o.id from opportunity o
left outer join opportunity_volunteer ov on o.id = ov.opportunity_id
left outer join volunteer v on ov.volunteer_id = v.id
where ov.id is null;
其中opportunity_volunteer
是链接表
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Volunteer", inversedBy="opportunities", cascade={"persist"})
* @ORM\JoinTable(name="opportunity_volunteer",
* joinColumns={@ORM\JoinColumn(name="opportunity_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="volunteer_id", referencedColumnName="id")}
* ))
*/
protected $volunteers;
public function addVolunteer(\Vol\VolBundle\Entity\Volunteer $volunteer) {
$volunteer->addOpportunity($this);
array_push($volunteers, $volunteer);
}
public function getVolunteers() {
return $this->volunteers;
}
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Opportunity", mappedBy="volunteers")
*/
protected $opportunities;
public function addOpportunity(\Vol\VolBundle\Entity\Opportunity $opportunity) {
array_push($opportunities, $opportunity);
}
public function getOpportunities() {
return $this->opportunities;
}
答案 0 :(得分:1)
从DQL docs读取,您应该使用WITH而不是WHERE来限制连接。在文档中搜索代码段“通过附加条件限制JOIN子句”。我想它应该是这样的:
return $this->getEntityManager()
->createQuery(
'SELECT p FROM VolVolBundle:Opportunity p '
. 'LEFT JOIN VolVolBundle:Volunteer v'
. 'WITH v.id IS null '
. 'ORDER BY p.organization ASC'
);
但这并未经过测试。
答案 1 :(得分:0)
最终的解决方案是创建1:n:1关系,消除中间的“隐形”实体。这样就可以在关系中添加字段。因此,除了在连接之前确保每行以空格字符结束之外,还需要重写查询。它现在可以根据需要找到空结果:
return $this->getEntityManager()
->createQuery(
'SELECT p FROM VolVolBundle:Opportunity p '
. 'LEFT JOIN VolVolBundle:OpportunityVolunteerEmail e '
. 'with p = e.opportunity '
. 'where e.opportunity is null'
. 'ORDER BY p.organization ASC'
)->getResult();