使用Symfony 4.2和Doctrine,我想禁用自动查询。
如果我执行以下简单示例:
$posts = $em->getRepository(Post::class)->findAll();
foreach ($posts as $post) {
dump($post->getCategory()->getName();
}
Doctrine会自行搜索类别。 但是我想禁用它。强迫我加入(存储库中的LEFT或INNER )。
有可能吗?谢谢
答案 0 :(得分:4)
通过访问链接的实体属性从数据库中获取隐式数据是Doctrine的核心原则之一,不能禁用。如果您只想显式地获取某些数据,则需要构造自己的部分查询并将数据混合为数组或简单对象,以使获取的结果不会成为实体。
答案 1 :(得分:2)
除您的意愿外,没有任何事情可以自动禁用此行为并迫使您编写JOIN子句。
此行为(称为延迟加载)是所有ORM的主要常见行为之一。
如果对此不满意(并且您可能有充分的理由),则可以考虑编写自己的DQL查询,该查询仅限于所选字段。查询中没有的内容将不会自动获取。
将此方法写入您的自定义PostRepository类中:
public function findAll(){
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('p')
->from('Post', 'p');
return $qb->getQuery()->getResult();
}
然后在您的控制器中,您可以执行与之前相同的操作:
$posts = $em->getRepository(Post::class)->findAll();
foreach ($posts as $post) {
dump($post->getCategory()->getName();
}
现在从getName()
实体调用Category
方法将引发错误,并且不会在后面启动任何隐藏的SQL查询。如果您想同时使用“帖子”和“类别”,则可以像这样修改findAll()
方法:
public function findAll(){
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('p, c')
->from('Post', 'p');
->join('p.category', 'c')
return $qb->getQuery()->getResult();
}