Symfony2 / Doctrine如何存储实体内相关对象的数量 [英] Symfony2/Doctrine How to store count of related objects within an Entity

查看:105
本文介绍了Symfony2 / Doctrine如何存储实体内相关对象的数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设置了一个包含测试对象的bundle,它包含一些testQuestion对象,每个对象都是一个问题和给定的答案(如果没有回答,则为0)。从树枝我想要能够从测试对象获取信息,以说出有多少个问题和有多少问题被回答。



我已经创建了一个查询,将其从数据库中提取出来,而在测试实体中,我创建了两个新的属性来存储问题数量和答案。我创建了一个查询所在的TestRepository。 Test对象检查对象是否具有设置的值,如果不需要加载,那么我不会总是需要这些信息。



但是我被卡住了关于如何将存储库代码链接到测试对象,无论是调用repo函数还是repo函数将值保存到相关的Test对象。



Acme / Quizbundle / Test / Test.php

 命名空间Acme\QuizBundle\Entity; 

使用Doctrine\ORM\Mapping作为ORM;
使用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 / Test / TestRepository.php(getNumQuestions有一个匹配的方法())

 命名空间Acme\QuizBundle\Entity; 

使用Doctrine\ORM\EntityRepository;

class TestRepository扩展EntityRepository {

私有函数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);
}


解决方案

您可以使用的模式来实现此结果,其中最简单的是简单地使用。它在修改后存储信息,而不是在每次需要时对它们进行计算。



另一个解决方案是在您的测试和测试之间创建一对多关联TestQuestion存储库(假设没有一个),那么在你的twig模板中,你可以简单地使用 {{testEntity.questionsAnswered.count()}} - 你甚至可以告诉教义使其成为超懒惰协会,以便它使用COUNT SQL语句来查找有多少个回答问题(默认情况下,当您尝试枚举关联时实际上会提取问题实体)。


$ b $最后,有一种方法,我不建议高度,但可能需要根据你的情况。与您在问题中使用的方法类似,您可以在存储库中获取问题数量,但要遵循Symfony的简单模型方法,您不要从实体内部启动查询(因为实体不应该有关于实体管理器/存储库)。



相反,您可以在加载Test实体的实例时使用Doctrine EventListener通知(参见这里,使用postLoad事件),然后调用您的存储库方法并将其设置在实体上那里。


I have set up a bundle that has a test object which holds a number of testQuestion objects each of which is a question and the given answer (or 0 if no answer). From twig I want to be able to get the information from the test object to say how many questions there are and how many have been answered.

I have created a query to pull this out of the db, and in the Test Entity I have created 2 new properties to store the number of questions and the number answered. I have created a TestRepository inside which the query resides. The Test object checks to see if the object has the value set and if not loads it when needed as I won't always need this information.

However I'm stuck on how to link the repository code to the test object, both to call the repo function and for the repo function to save the values to the relevant Test object.

Acme/Quizbundle/Test/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/Test/TestRepository.php (There's a matching method for 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);
    }

解决方案

There are a number of different patterns you can use to achieve this result, the simplest of which is to simply use an aggregate field. This stores the information after it's modified, rather than calculating it each time that it's needed.

An alternate solution is to create a one-to-many association between your Test and TestQuestion repositories (assuming that there isn't one already), then in your twig template you can simply use {{ testEntity.questionsAnswered.count() }} - you can even tell Doctrine to make this an "extra-lazy" association so that it uses the COUNT SQL statement to look up how many answered questions there are (by default it actually fetches the question entities when you try to enumerate the association).

Finally, there's the method that I wouldn't recommend highly, but might be required depending on your situation. Similar to the approach that you use in your question, you fetch the question count in your repository, but to keep with Symfony's simple Model approach, you don't kick off the query from inside the entity (as the entity should never have information about the entity manager/repository).

Instead, you can use a Doctrine EventListener to be informed whenever an instance of your Test entity is loaded (see here, using the postLoad event), then call your repository method and set it on the entity from there.

这篇关于Symfony2 / Doctrine如何存储实体内相关对象的数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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