我试图找出所有艺术家列表,他们是否具有角色,但我当前的查询仅显示在数据库中具有角色的艺术家姓名:
这是我的查询:
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('MyAppBundle:Artist')
->createQueryBuilder('c')
->select('c.id, c.name, c.sex, c.priority, c.bday, c.bmonth, c.byear,IDENTITY(co.content) as work')
->addSelect('IDENTITY(co.content) as work, IDENTITY(co.role) as roles')
->innerJoin('c.cast_and_crews', 'co')
->getQuery()
->getArrayResult();
foreach ($entities as &$artist) {
$role = $em->getRepository('MyAppBundle:Role')
->createQueryBuilder('e')
->select('e.name')
->where('e.id = :id')
->setParameter('id', $artist['roles'])
->getQuery()
->getResult();
$artist['role'] = ($role[0]['name']);
而且它的查询时间也非常非常糟糕。我的表中有 9000 行,此查询查询我从探查器中看到的所有 9000 行,花费了 1000 多毫秒。此外,在此查询中仅显示一个角色,但一位艺术家可能具有多个角色,如何将其保留在 artis['role']
中?
谁能提出一个好的解决方案吗?
最佳答案
使用leftJoin()
而不是innerJoin()
。
假设 Country 实体有许多 League 实体。此外,有些国家没有任何联赛。
协会:
class Country
{
protected $id;
/**
* @ORM\OneToMany(
* targetEntity="League",
* mappedBy="country",
* cascade={"persist", "remove"}
* )
*/
protected $league;
}
class League
{
protected $id;
/**
* @ORM\ManyToOne(
* targetEntity="Country",
* inversedBy="league"
* )
* @ORM\JoinColumn(
* name="country_id",
* referencedColumnName="id",
* onDelete="CASCADE",
* nullable=false
* )
*/
protected $country;
}
示例查询:
public function findAll()
{
return
$this
->createQueryBuilder('c')
->select('c, l')
->leftJoin('c.league', 'l')
->orderBy('c.name', 'ASC')
->getQuery()
->getResult();
}
上面的示例将返回与国家/地区和联赛相关的数据,因此您可以看到,我没有像您一样运行循环来从其他实体中选择数据,因为查询已经返回了我需要的所有内容。
Controller 中的结果:
如您所见,结果也包括联赛。
$country = $repo->findAll();
foreach ($country as $c) {
echo $c->getId() . ' -> ' . $c->getName() . PHP_EOL;
foreach ($c->getLeague() as $l) {
echo $l->getId() . ' -> ' . $l->getName() . PHP_EOL;
}
}
现在您可以继续为自己创建一个ONLY ONE查询,就像我上面所做的那样。
我想你的会是这样的:
public function findAll()
{
return
$this
->createQueryBuilder('a')
->select('a, r')
->leftJoin('a.role', 'r')
->orderBy('a.name', 'ASC')
->getQuery()
->getResult();
}
$artist = $repo->findAll();
foreach ($artist as $a) {
echo $a->getId() . ' -> ' . $a->getName() . PHP_EOL;
foreach ($a->getRole() as $r) {
echo $r->getId() . ' -> ' . $r->getName() . PHP_EOL;
}
}
关于php - Symfony 查询生成器将所有结果添加到结果集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30679272/