2016-01-22 129 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

我不知道爲什麼。與失去的表現交易是一個很大的理由。 –