查询 n = null 的 m:n 关系 - 返回 Lexer 错误

问题描述 投票:0回答:2

构建查询以选择没有对应 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;
}
php symfony doctrine-orm many-to-many
2个回答
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'
    );

但这还没有经过测试。


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();
© www.soinside.com 2019 - 2024. All rights reserved.