从Doctrine2和Symfony2的单向许多关系获取实体 [英] Get entities from a unidirectional many to many relation with Doctrine2 and Symfony2

查看:97
本文介绍了从Doctrine2和Symfony2的单向许多关系获取实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开展语言评估项目,使您能够以所需的语言考试并评估您的水平。我使用Symfony2框架,并与Doctrine2一起使用。我的问题如下:

I'm currently working on a language assessment project which enables you to take an exam in the language you want and evaluate your level. I use Symfony2 framework and work with Doctrine2 as well. My issue is the following one:

我有两个实体通过多对多关系链接的考试和问题(考试是所有者)。每个考试可以与几个问题相关,每个问题都可以与几个考试相关。

I have two entities Exam and Question linked by a Many-To-Many relation (Exam being the owner). Each exam can be related to several questions, and each question can be related to several exams.

这是我的代码:

考试实体

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

只要它是一个单向关系,我的问题课程中没有考试属性。

As long as it is a unidirectional relation, there is no 'exams' attribute in my Question class.

现在,我想做的是获得与特定考试相关的所有问题,调用getQuestions()方法,像这样:

Now, what I want to do is getting all the questions related to a specific exam, calling the getQuestions() method, like this:

$questions = $exam->getQuestions();

但是这个方法返回一个空数组,即使我的数据库中有数据。如果我var_dump的$ exam变量,我可以看到问题数组是空的:

But this method returns an empty array, even if I have data in my database. If I var_dump the $exam variable, I can see the questions array is empty:

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()函数,但是在这种情况下我并不知道如何实现联接。

I think I could maybe write a findByExam() function in my QuestionRepository, but I don't really know how to implement the joins in this case.

任何帮助都会很棒! p>

Any help would be great!

推荐答案

要在您的QuestionRepository中使用findByExam()方法执行以下操作:

To have a findByExam() method in your QuestionRepository do the following:

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

    return $q->getResult();
 }

您还可以创建双向关系不是单向的! p>

You could also create a bi-directional relationship not uni-directional !


每个考试都可以与几个问题相关,每个问题可以
与几个考试相关。

Each exam can be related to several questions, and each question can be related to several exams.

通过将此添加到您的Question实体中创建双向关系:

Create a bi-directional relationship by adding this to your Question entity:

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

    // ...

之后你可以使用...

Afterwards you can use...

$question->getExams()

...在您的控制器中。

... in your controller.

要自动加入您的相关实体,doctrine的fetch选项可以与:

To automatically join your related entities doctrine's fetch option can be used with:


  • LAZY(加载访问时的关系)

  • EAGER(自动加入关系)

  • EXTRA_LAZY(手动提取)

示例:

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

尽管加载速度在性能方面有下降的可能

Though eager loading has a downside in terms of performance it might be an option for you.

使用EAGER获取原则


每当您查询具有持久关联的实体和
时,这些关联将映射为EAGER,它们将被l自动将
与要查询的实体一起加载,因此可以立即向您的应用程序

Whenever you query for an entity that has persistent associations and these associations are mapped as EAGER, they will automatically be loaded together with the entity being queried and is thus immediately available to your application.

教义文档中了解更多信息

在使用关系时应检查的另一个选项是级联选项。

Another option you should check when working with relations is the cascade option.

请参阅原则 - 使用协会章节。

提示:
您应该为考试和问题创建界面,并使用它们的原始实体在您的集合和添加方法以允许更容易扩展。

Tip: You should create interfaces for exams and questions and use them instead of the original entity in your set and add methods to allow easier extending.

这篇关于从Doctrine2和Symfony2的单向许多关系获取实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆