2012-07-13 39 views
5

我建立了一個包含一個測試對象的包,其中包含多個testQuestion對象,每個對象都是問題和給定的答案(如果沒有答案,則爲0 )。從樹枝上我希望能夠從測試對象中獲取信息,說明存在多少個問題以及有多少個答案。Symfony2/Doctrine如何在實體中存儲相關對象的數量

我已經創建了一個查詢來將其從數據庫中提取出來,並且在測試實體中,我創建了2個新屬性來存儲問題的數量和回答的數量。我創建了一個查詢所在的TestRepository。 Test對象檢查對象是否具有設置的值,如果不在需要時加載它,因爲我不會始終需要此信息。

但是我堅持如何將存儲庫代碼鏈接到測試對象,既要調用回購函數,又要用於回購函數以將值保存到相關的測試對象。

的Acme/Quizbundle /測試/ test.php的

namespace Acme\QuizBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Acme\QuizBundle\Entity\TestRepository; 

/** 
* @ORM\Entity(repositoryClass="Acme\QuizBundle\Entity\TestRepository") 
* @ORM\Table(name="test") 
*/ 
class Test { 
protected $numQuestions = null; 
protected $numQuestionsAnswered = null; 

public function getNumQuestionsAnswered() { 
    if (is_null($this->numQuestionsAnswered)) { 
     $repository = $this->getEntityManager()->getRepository('\AcmeQuizBundle\Test'); 
     $values = $repository->calculateNumQuestions(); 
    } 
    return $this->numQuestionsAnswered; 
} 

的Acme/Quizbundle /測試/ TestRepository.php(有用於getNumQuestions()的匹配方法)

namespace Acme\QuizBundle\Entity; 

use Doctrine\ORM\EntityRepository; 

class TestRepository extends EntityRepository { 

private function calculateNumQuestions() { 

    $qb = $this->getEntityManager() 
       ->createQueryBuilder(); 

    $query = $this->getEntityManager()->createQueryBuilder() 
         ->select('COUNT(id)') 
      ->from('testquestion', 'tq') 
      ->where('tq.test_id = :id') 
      ->setParameter('id', $this->getId()) 
      ->getQuery(); 

    $result = $query->getSingleScalarResult(); 
    var_dump($result); 
    } 

回答

12

有許多你可以使用不同的圖案來達到這個效果,其中最簡單的就是簡單地使用aggregate field。這會在修改後存儲信息,而不是在每次需要時計算它。

另一種解決方案是在Test和TestQuestion庫之間建立一對多的關聯(假設已經沒有),然後在你的樹枝模板中你可以簡單地使用{{ testEntity.questionsAnswered.count() }} - 你甚至可以告訴Doctrine使其成爲"extra-lazy" association,以便它使用COUNT SQL語句查找有多少個回答的問題(默認情況下,當您嘗試枚舉關聯時,它實際上會提取問題實體)。

最後,有一種方法我不會高度推薦,但可能需要根據您的情況而定。與您在問題中使用的方法類似,您可以在存儲庫中獲取問題計數,但爲了與Symfony的簡單模型方法保持一致,您不會從實體內部啓動查詢(因爲實體永遠不會獲得有關實體管理器/存儲庫)。

相反,只要加載了Test實體的實例(請參閱here,使用postLoad事件),就可以使用Doctrine EventListener來通知您,然後調用您的存儲庫方法並將其設置在實體上。

+0

謝謝,這真的很有幫助 – 2012-07-14 15:19:53

+0

要小心!! 1如果使用額外的懶惰關聯,您必須使用'Collection#count()'call **來代替內置的小枝**'lenght'。 **正確的方法將使用SQL COUNT:**'{{testEntity.questionsAnswered.count}}'('| length'將導致在內存中獲取行!) – 2017-01-29 09:53:20

+0

感謝您更正@Sanya_Zol,相應地更新了答案 – 2017-01-29 13:57:09

相關問題