禁用教义自动查询

时间:2019-02-25 09:46:40

标签: mysql symfony doctrine-orm doctrine symfony4

使用Symfony 4.2和Doctrine,我想禁用自动查询。

如果我执行以下简单示例:

$posts = $em->getRepository(Post::class)->findAll();

foreach ($posts as $post) {
    dump($post->getCategory()->getName();
}

Doctrine会自行搜索类别。 但是我想禁用它。强迫我加入(存储库中的LEFT或INNER )。

有可能吗?谢谢

2 个答案:

答案 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();
}