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.
从 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.