2013-05-22 91 views
6

我目前正在開發一個語言評估項目,使您能夠以所需語言參加考試並評估您的水平。我使用Symfony2框架並與Doctrine2一起工作。我的問題是以下一種:從Doctrine2和Symfony2獲取單向多對多關係

我有兩個實體考試和問題由多對多關係(考試是所有者)相關聯。每個考試可以涉及幾個問題,每個問題都可以與多個考試相關。

這裏是我的代碼:

考試實體

/** 
* Exam 
* 
* @ORM\Table(name="cids_exam") 
* @ORM\Entity(repositoryClass="LA\AdminBundle\Entity\ExamRepository") 
*/ 
class Exam 
{ 
    ... 

    /** 
    * @ORM\ManyToMany(targetEntity="LA\AdminBundle\Entity\Question", cascade={"persist"}) 
    * @ORM\JoinTable(name="cids_exam_question") 
    */ 
    private $questions; 

    ... 


    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->questions = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * Add questions 
    * 
    * @param \LA\AdminBundle\Entity\Question $questions 
    * @return Exam 
    */ 
    public function addQuestion(\LA\AdminBundle\Entity\Question $questions) 
    { 
     $this->questions[] = $questions; 

     return $this; 
    } 

    /** 
    * Remove questions 
    * 
    * @param \LA\AdminBundle\Entity\Question $questions 
    */ 
    public function removeQuestion(\LA\AdminBundle\Entity\Question $questions) 
    { 
     $this->questions->removeElement($questions); 
    } 

    /** 
    * Get questions 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getQuestions() 
    { 
     return $this->questions; 
    } 
} 

只要它是一個單向的關係,存在於我的問題類中沒有「考試」屬性。

現在,我想要做的是讓所有與特定的考試問題,調用getQuestions()方法,像這樣:

$questions = $exam->getQuestions(); 

但這種方法即使返回一個空數組,我在我的數據庫中有數據。如果我的var_dump的$考試變量,我能看到的問題數組爲空:

object(LA\AdminBundle\Entity\Exam)[47] 
    private 'id' => int 5 
    ... 
    private 'questions' => 
    object(Doctrine\ORM\PersistentCollection)[248] 
     private 'snapshot' => 
     array (size=0) 
      empty 
     private 'owner' => null 
     private 'association' => null 
     private 'em' => null 
     private 'backRefFieldName' => null 
     private 'typeClass' => null 
     private 'isDirty' => boolean false 
     private 'initialized' => boolean false 
     private 'coll' => 
     object(Doctrine\Common\Collections\ArrayCollection)[249] 
      private '_elements' => 
      array (size=0) 
       ... 

我想我可能會寫一findByExam()函數在我QuestionRepository,但我真的不知道如何實現的在這種情況下加入。

任何幫助將是偉大的!

回答

11

要在你的QuestionRepository一個findByExam()方法執行以下操作:

public function findByExam($exam) 
{ 
    $q = $this->createQueryBuilder('q') 
     ->where('q.exam = :exam') 
     ->setParameter('exam', $exam) 
     ->getQuery(); 

    return $q->getResult(); 
} 

您還可以創建一個雙向的關係不是單向的!

每個考試都可以涉及到幾個問題,每個問題都可以涉及多個考試。在您的控制器

use Doctrine\Common\Collections\Collection; 
use Doctrine\Common\Collections\ArrayCollection; 
use Vendor\YourExamBundle\Entity\ExamInterface; 

class Question 
{ 
    protected $exams; 

    public function __construct() 
    { 
     $this->exams = new ArrayCollection(); 
    } 

    public function getExams() 
    { 
     return $this->exams; 
    } 

    public function addExam(ExamInterface $exam) 
    { 
     if !($this->exams->contains($exam)) { 
      $this->exams->add($exam); 
     } 
     return $this; 
    } 

    public function setExams(Collection $exams) 
    { 
     $this->exams = $exams; 

     return $this; 
    } 

    // ... 

之後,您可以使用...

$question->getExams() 

...:

創建加給你的問題的實體雙向的關係。

自動加入您的相關實體學說的提取選項可用於:

  • LAZY(訪問時加載的關係)
  • EAGER(自動連接關係)
  • EXTRA_LAZY(手動取)

例如:

/** 
* @ManyToMany(targetEntity="Question",inversedBy="exams", cascade={"all"}, fetch="EAGER") 
*/ 

儘管急切的加載在性能方面有不利影響,但它可能是您的選擇。

主義充滿渴望的

取每當您查詢的是具有持續性關聯和 這些關聯映射一樣渴望一個實體,他們將自動 與實體一起加載被查詢,因此立即向您的應用程序提供 。

Doctrine Documentation瞭解更多關於它的信息。

您應該檢查什麼時候處理關係的另一個選項是級聯選項。

查看文檔的Doctrine - Working with Associations章節。

提示: 您應該創建考試和問題的接口和你的集合,而不是使用它們原來的實體,並添加方法來允許擴展更加容易。

+0

感謝您的偉大的答案!這將有很大幫助。如果我解決了我的問題或遇到了其他問題,我會盡力解決問題;) – Beliasus

+0

我嘗試創建雙向關係而不是單向關係,但仍無法獲取任何內容。你認爲這可能是控制器中的一個問題,就在堅持考試及其相關問題進入數據庫之前?我可能不得不實際將每個問題添加到考試實例?我的意思是你知道如果表單中的綁定請求會調用addQuestion()函數,還是必須手動執行? – Beliasus

+0

找了好幾個小時後,我意識到我的問題根本不是來自多方面的關係,而是來自其他干擾它的事情。實際上,考試實體中的getQuestions()函數是有效的,這是以單向關係做我想做的事情的最佳方式。感謝您的幫助,我使用您的建議添加功能,並且很好地看待了教義獲取。 – Beliasus

0

使用Doctrine2 ORM與關聯表exam_questions雙向關係 exam_id question_id

<?php 

class Exams 

....OTHER PROPERTIES... 

/** 
    * Owning Side 
    * 
    * @ManyToMany(targetEntity="Questions", inversedBy="exams") 
    * @JoinTable(name="exam_questions", 
    *  joinColumns={@JoinColumn(name="exam_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@JoinColumn(name="question_id", referencedColumnName="id")} 
    *  ) 
    */ 
private $questions; 

..OTHER CODES.. 

} 


class Questions{ 


..OTHER CODES.. 

/** 
    * Inverse Side 
    * 
    * @ManyToMany(targetEntity="Exams", mappedBy="questions") 
    */ 
private $exams; 

..OTHER CODES.. 

} 

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-manytomany