2013-05-22 4 views
6

현재 원하는 언어로 시험에 응시하고 레벨을 평가할 수있는 언어 평가 프로젝트를 진행 중입니다. Symfony2 프레임 워크를 사용하고 Doctrine2에서도 작업합니다. 내 이슈는 다음과 같습니다 :Doctrine2 및 Symfony2와 단방향 다 대다 관계의 엔티티 가져 오기

나는 Many-To-Many 관계 (Exam는 소유자 임)에 의해 링크 된 두 개의 엔티티 Exam과 Question를 가지고 있습니다. 각 시험은 몇 가지 질문과 관련 될 수 있으며 각 질문은 여러 시험과 관련 될 수 있습니다. 한은은 단방향 관계이므로

시험 기관

/** 
* 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(); 

그러나이 방법은 경우에도 빈 배열을 반환합니다 I 데이터베이스에 데이터가 있습니다. 나는 $ 시험 변수를 위해서 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) 
       ... 

나는 어쩌면 내 QuestionRepository에 findByExam() 함수를 쓸 수 있다고 생각하지만, 난 정말 구현하는 방법을 모른다 이 경우에는 조인합니다.

도움이 될 것입니다.

답변

11

는 다음을 수행하여 QuestionRepository에 findByExam() 메소드를하려면, 당신은 또한 양방향 관계를 단방향하지 만들 수

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

    return $q->getResult(); 
} 

!

각 시험은 여러 가지 질문과 관련 될 수 있으며 각 질문은 여러 시험과 관련 될 수 있습니다. 컨트롤러에 ...

$question->getExams() 

을 이후

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; 
    } 

    // ... 

사용할 수 :

는 질문 법인이를 추가하여 양방향 관계를 만듭니다.

  • LAZY (액세스 할 때 관계를로드)
  • 는 EAGER (관계를 자동 조인)
  • EXTRA_LAZY (수동 가져 오는 :

    자동으로 관련 기관 교리의 옵션을 가져가 사용할 수 있습니다 가입하려면)

예 :

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

열심히로드하는 것이 성능면에서 단점이 있지만 옵션 일 수 있습니다.

당신이 EAGER로 매핑되어 지속적 협회와 이러한 연관성이있는 개체를 조회 할 때마다 교리는, EAGER

로 가져 오기가 자동으로 개체와 함께로드 될 것이다 쿼리 때문에입니다되고 즉시 을 애플리케이션에서 사용할 수 있습니다.

Doctrine Documentation에서 자세한 내용을 읽어보십시오.

관계를 사용할 때 확인해야 할 또 다른 옵션은 계단식 옵션입니다.

설명서의 Doctrine - Working with Associations 장을 참조하십시오.

팁 : 시험 및 질문 용 인터페이스를 만들어 세트의 원래 엔티티 대신 사용하고 더 쉽게 확장 할 수있는 방법을 추가해야합니다. 관련 테이블 exam_questions와 Doctrine2 ORM을 사용

+0

감사 question_id! 그것은 많은 도움이 될 것입니다. 나는 그것에 대해 연구 할 것이고 나의 문제를 해결했거나 다른 사람들과 만났을 때 알려주겠다.) – Beliasus

+0

나는 단방향 대신에 양방향 관계를 만들려고 노력했지만, 여전히 나는 아무것도 얻을 수 없다. 관련 질문이있는 시험을 데이터베이스에 지속하기 직전에 컨트롤러에서 문제가 될 수 있다고 생각하십니까? 실제로 각 질문을 시험 인스턴스에 추가해야 할 수도 있습니다. 폼에서 바인드 요청이 addQuestion() 함수를 호출하는지 또는 수동으로 수행해야 하는지를 알 수 있습니까? – Beliasus

+0

몇 시간 동안 수색을 한 후에, 나는 내 문제가 많은 관계에서 많은 관계로 오는 것이 아니라 그것을 방해하고있는 다른 것에서 오는 것이란 것을 깨달았다. 실제로, Exam 엔터티의 getQuestions() 함수가 작동합니다. 그리고 이것은 단방향 관계로 원했던 것을 수행하는 가장 좋은 방법입니다. 도움을 주셔서 감사합니다. 추가 기능에 대한 조언을 사용했으며 Doctrine Fetching도 잘 보았습니다. – Beliasus

0

양방향 관계는 exam_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

관련 문제