我已经设置了一个包,其中包含一个测试对象,该对象包含多个 testQuestion 对象,每个对象都是一个问题和给定的答案(如果没有答案则为 0)。我希望能够从 twig 中获取测试对象的信息,以说明有多少问题以及已回答了多少问题。
我创建了一个查询来将其从数据库中提取出来,并在测试实体中创建了 2 个新属性来存储问题数量和回答数量。我创建了一个 TestRepository,查询驻留在其中。测试对象检查该对象是否已设置值,如果没有,则在需要时加载它,因为我并不总是需要此信息。
但是,我坚持如何将存储库代码链接到测试对象,既调用 repo 函数,又让 repo 函数将值保存到相关的 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/Test/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);
}
您可以使用多种不同的模式来实现此结果,其中最简单的就是简单地使用聚合字段 https://www.doctrine-project.org/projects/doctrine-orm/en/current/cookbook/aggregate-fields.html。这会在修改后存储信息,而不是每次需要时都进行计算。
另一种解决方案是在 Test 和 TestQuestion 存储库之间创建一对多关联(假设还没有),然后在您的 twig 模板中您可以简单地使用{{ testEntity.questionsAnswered.count() }}
- 你甚至可以告诉 Doctrine 将其设为“超懒”协会 https://www.doctrine-project.org/projects/doctrine-orm/en/current/tutorials/extra-lazy-associations.html#extra-lazy-associations因此它使用 COUNT SQL 语句来查找有多少已回答的问题(默认情况下,当您尝试枚举关联时,它实际上会获取问题实体)。
最后,有一种方法我不会强烈推荐,但根据您的情况可能需要。与您在问题中使用的方法类似,您在存储库中获取问题计数,但为了与 Symfony 的简单模型方法保持一致,您不会从实体内部启动查询(因为实体永远不应该拥有有关实体管理器/存储库)。
相反,您可以使用 Doctrine EventListener 在加载测试实体的实例时收到通知(请参阅here https://symfony.com/doc/current/doctrine/events.html#doctrine-lifecycle-subscribers,使用 postLoad 事件),然后调用您的存储库方法并将其设置在实体上。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)