2016-01-22 123 views
0

我对于为什么教义查询以这种特定方式工作感到有点困惑。假设我们有文章和用户实体,用户与文章具有OneToMany关系。学说相关实体附加查询

然后,在控制器中,我们将获取所有文章并将它们发送到视图。

$em = $this->getEntityManager();  
$articles = $em->getRepository('MyBundle:Article')->findAll(); 

而在视图中我们会循环它们。

{% for article in articles %} 
    {{ article.author.name }} 
{% endfor %} 

的这里的问题是,这段代码确实为所有报道的额外查询(文章的用户)。

我知道我们可以使用DQL,但是我的问题是Doctrine如何在这里工作,为什么不为这种事情优化,这很常见?我觉得这是通过应用程序常用的'错误',这真的会减慢它们的速度。我刚刚发现了这一点,现在我必须将很多查询重写到我的控制器中。

这也违背了ORM的目的,它实际上应该提供写入应用程序的速度。这迫使我们编写DQL/QB查询,而不是利用ORM。那么,如果ORM表现如此糟糕,那么ORM什么时候才能使用?

+0

考虑扫描文档:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/ – Cerad

+0

查看渴望与懒惰的抓取,你就会开始理解。 – Daniel

+0

渴望获取的问题在于,即使不需要,也会始终提取相关实体。 –

回答

2

据我所知,我们可以使用DQL,但我的问题是如何工作的学说在这里,为什么不是它这种事情,这是很常见的优化?

学说不能猜测你在Twig视图上需要什么值。

但是,为什么它不在视图中创建查询,当我调用相关实体?为什么它会创建单独的查询?

这不可能是解决方案。看你的代码:

{% for article in articles %} 
    {{ article.author.name }} 
{% endfor %} 

要知道什么样的价值观,你将不得不显示,Symfony的应该迭代循环才能猜什么价值,你需要,这将是一个大量的工作,获取数据之前。


你可以明确地告诉教义什么表协会应被添加到查询:

ArticleRepositoryrepository,你必须join相关表:

<?php 

namespace Acme\Bundle\AcmeBundle\Entity; 

use Doctrine\ORM\EntityRepository; 

class ArticleRepository extends EntityRepository 
{ 
    public function getArticlesWithAuthors() 
    { 
     $qb = $this->createQueryBuilder('article'); 

     $query = $qb 
      ->select('article, author') 
      ->innerJoin('article.author', 'author') 
      ->orderBy('a.id', 'DESC') 
     ; 

     return $query->getQuery()->getResult(); 
    } 
} 

然后你就可以请拨打方法:

$articles = $em->getRepository('MyBundle:Article')->getArticlesWithAuthors(); 

和学说将在同一查询中加载与该文章关联的作者。

+0

“要知道你需要展示什么值,Symfony应该循环遍历循环,以便猜测你将需要什么值,在获取数据之前这将是很多工作。” - 从技术上讲,它不能执行查询,直到它获得控制器和视图所需的数据,并基于这两者进行查询而不是进行2个查询。 –

+0

@GeorgeIrimiciuc是的,你应该可以让Doctrine遍历循环并找到需要的值。无论如何,如果你看一下Profiler,你会发现查询是在Controller中执行的。我认为这是Symfony在渲染Twig模板之前缓存Doctrine结果的决定。 –

+0

我不知道为什么。与失去的表现交易是一个很大的理由。 –