Symfony 4,ManyToOne 实体关系,仅当至少一个子项包含特定值时才获取 'parents',错误 "Expected end of string, got 'ON'"

Symfony 4, ManyToOne entities relation, get 'parents' only if at least one child contains a specific value, Error "Expected end of string, got 'ON'"

从 Symfony 4 开始,我在实体 A 和 B 之间建立了 ManyToOne 关系(多个 B 对应一个 A)。仅当 'child' B 在其特定字段中具有值 1 时,我才需要 select 所有 id 的 A 行。

table 'A' :

---
id 
---
0
1
2

table 'B' :

----------------------------------
id    parent_id    specificfield 
----------------------------------
0     1            1
1     1            0
2     2            0

预期结果:

---
id 
---
1 
// because, only the A row with the id 1 have at least one 'child' in the table B with the specificfield set to 1 

我尝试构建这样的查询:

$res = $this->em->createQueryBuilder()
    ->select('A.id')
    ->from(Parent::class,'A')
    ->innerJoin(Child::class,'B',Join::ON,"A.id = B.parent_id")
    ->where('B.specificfield = 1')
    ->distinct()
    ->getQuery()
    ->getResult();

但我收到错误消息:"Expected end of string, got 'ON'"

sql 等效查询在我的 phpmyadmin 中有效..

SELECT DISTINCT A.id
FROM parent A
INNER JOIN child B ON A.id = B.parent_id
WHERE e.specificfield = 1

我看不出我的 dql 查询哪里出错了..

我认为您需要在联接中使用 "with" 而不是 "on"...

使用 ORM 时,您是在直接处理实体而不是表。这需要您以不同的方式思考,尤其是在关联方面。您正在加入实体的属性,而不是 tables/objects.

之间

因此查询如下所示:

$builder
    ->select('a.id')
    ->from(A::class, 'a')
    ->innerJoin('a.children', 'b')
    ->where('b.active = 1')
    ->getQuery()
    ->getResult();

所以您只需指定要加入的属性,因为您的映射已经指定了哪个实体属于那里,所以它应该可以工作。作为参考,这是我的实体的样子:

/**
 * @ORM\Entity()
 */
class A
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\B", mappedBy="parent")
     */
    private $children;

    ...
}
/**
 * @ORM\Entity()
 */
class B
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\A", inversedBy="children")
     * @ORM\JoinColumn(nullable=false)
     */
    private $parent;

    /**
     * @ORM\Column(type="boolean", options={"default": false})
     */
    private $active;

    ...
}

编辑澄清:当您加入 B::class 而不是 a.children 时。然后你只需告诉查询构建器你想一次不相关地获取多个实体。如果您想通过一次查询快速收集所有 As 和活动 B,但您还必须 select b.id.