我有一个Restaurant
实体,可以有很多Cuisines
(意大利语,寿司等):
/**
* @ORM\Entity
*/
class Restaurant
{
/**
* @ORM\ManyToMany(targetEntity="Cuisine")
*/
protected $cuisines;
}
当我加载餐馆列表时,我想急切地加载它的菜肴,以避免在每家餐厅调用getCuisines()
时往返数据库。使用DQL:
SELECT r, c
FROM Model\Restaurant r
LEFT JOIN r.cuisines c
一切都很好。
现在如果我想要归还所有包含特定美食的餐馆,我可以使用这个DQL:
SELECT r
FROM Model\Restaurant r
LEFT JOIN r.cuisines c
WHERE c.id IN (?)
那也很好。现在,如果我想同时做两件事:
SELECT r, c
FROM Model\Restaurant r
LEFT JOIN r.cuisines c
WHERE c.id IN (?)
餐馆列表是正确的,但他们的$cuisines
只会填充ID与给定列表匹配的餐馆。这完全打破了模式。
我如何通过美食限制退回的餐厅,同时仍然渴望加载完整的美食列表?
答案 0 :(得分:0)
如果你不介意总是急切负担美食:
/**
* @ManyToMany(targetEntity="Cuisine", fetch="EAGER")
*/
否则......很难。如果是OneToMany
,您可以暂时更改该查询:http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#temporarily-change-fetch-mode-in-dql
但是使用ManyToMany
,您无法在每个查询的基础上执行此操作。
答案 1 :(得分:0)
也许我错了,但通常你应该能够获得整个ArrayCollection而不在查询中指定它。
$qb = $em->createQueryBuilder();
$qb->select('r')
->from('Model\Restaurant', 'r')
->leftJoin('r.cuisines', 'c')
->where('c.id IN ?1')
->setParameter(1, $ids);
$query = $qb->getQuery();
$result = $query->getResult();
foreach ($result as $restaurant){
//contains the whole arrayCollection
var_dump($restaurant->getCuisines());
}
在您的餐厅实体中确保有一个构造函数。
public function __construct() {
$this->cuisines = new ArrayCollection();
}
答案 2 :(得分:0)
在您当前的查询中,您通过Cuisines
模型的属性限制结果集 - 因此您无法获得您尝试获取的餐馆的所有关系。尝试使用如下的子选择:
SELECT r, c
FROM Model\Restaurant r
LEFT JOIN r.cuisines c
WHERE r.id IN (
SELECT DISTINCT sr.id
FROM Model\Restaurant sr
LEFT JOIN sr.cuisines sc
WHERE sc.id IN (?)
)
说明:子选择执行您在上面开发的同一查询,以同时获取两者。但是,我们只返回符合标准的餐馆ID。然后,在主要选择中,我们用所有他们的菜肴来获取所有这些餐馆。