【发布时间】:2016-01-23 15:10:08
【问题描述】:
我在两个表(franchise 和 player)之间有一个多对多关联,由一个额外的表(franchise_players)构建。 我已经创建了三个实体:
class Franchise
{
...
/**
*
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="NBA\Entity\FranchisePlayer", mappedBy="franchise")
*/
private $franchiseplayers;
...
}
class Player
{
/* some fields */
}
class FranchisePlayers
{
...
/**
* @var \NBA\Entity\Player
*
* @ORM\ManyToOne(targetEntity="NBA\Entity\Player")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="playerId", referencedColumnName="id")
* })
*/
private $player;
/**
* @var \NBA\Entity\Franchise
*
* @ORM\ManyToOne(targetEntity="NBA\Entity\Franchise")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="franchiseId", referencedColumnName="id")
* })
*/
private $franchise;
}
我的目标是获得所有特许经营权及其相关球员。
显而易见的解决方案简单但效率不高:
Get all franchises
foreach $franchise
$franchise->getFranchisePlayers()
foreach $franquisePlayer
$franquisePlayer->getPlayer()->getFullName();
另一种解决方案是获取所有特许经营权,然后执行左连接以获取每个特许经营权的相关玩家:
Get all franchises
foreach $franchise
public function getCurrentPlayers(Franchise $franchise) {
$qb = $this->entityManager->createQueryBuilder();
$qb->select(array('p'))
->from('NBA\Entity\Player', 'p')
->leftjoin('NBA\Entity\FranchisePlayer','f','WITH','f.player=p')
->where('f.franchise = ?1')
->orderBy('p.surname','ASC')
->setParameter(1,$franchise);
$query = $qb->getQuery();
return $query->getResult();
}
通过这种方式,我们减少了查询次数。
我的问题是我是否可以通过这样的一个查询来实现我的目标:
public function getFranchisesWithPlayers() {
$qb = $this->entityManager->createQueryBuilder();
$qb->select(array('f'))
->from('NBA\Entity\Franchise', 'f')
->leftJoin('NBA\Entity\FranchisePlayer','fp','WITH','fp.franchise=f')
->leftJoin('NBA\Entity\Player','p','WITH','fp.player=p')
->orderBy('f.name')
->addOrderBy('p.surname');
$query = $qb->getQuery();
return $query->getResult();
}
我认为 Franchise 实体的 FranchisePlayers 字段(以及每个 FranchisePlayer 的 de Player 实体)会自动加载,但似乎并非如此。
有可能吗?也许我在实体的映射中做错了什么?
谢谢!
编辑: 昨天我确信查询越少效率最高,但现在我怀疑了。也许水合这个复杂查询的结果的成本大于水合选项 2 查询的每个结果的成本(在不同的查询中查询每个特许经营的球员)。你怎么看?
【问题讨论】:
标签: doctrine-orm dql