请考虑以下情况:我有两个实体:Article
和ArticleComment
:
// \AppBundle\Entity\Article
/**
* @ORM\OneToMany(targetEntity="ArticleComment", mappedBy="article")
*/
private $comments;
我需要在文章的字段中存储评论数量(例如articles.comments_count
)。每当创建或删除评论时,都需要更新该字段。
以前我使用了内置CounterCache behavior的CakePHP框架,它自动执行此操作。我已经尽力为Doctrine 2找到类似的东西(从DoctrineExtensions库开始),但似乎没有什么可以做我正在寻找的东西。
任何执行此操作的库?或者我必须提出自己的解决方案吗?
编辑:我尝试使用Entity Events,但我在许多实体上需要这种行为,所以我对可重用的解决方案感兴趣
答案 0 :(得分:1)
您可以查看额外的懒惰关联。 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html
这样您就不需要存储comment_counter,因为您可以在集合中使用count()函数而无需加载完整集合。 在内部,Doctrine将发出一个" select count"查询。
答案 1 :(得分:0)
这是另一个答案,它可以避免存储此类聚合,并使您能够在评论中使用分页符。我还没有测试它,所以可能会有一些错误。
$qb = $em->createQueryBuilder();
$qb
->select('a.title, a.author, count(c)')
->from('Article', 'a')
->leftJoin('a.comments', 'c')
->groupBy('a.id');
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($qb, $page, $limit);
正如我所说,这个问题并不是真正与学说有关,因为你最初的模型设计很糟糕。 通常,您不需要存储可以使用count / groupby查询计算的聚合。 当你有很多连接的实体在计算过程中产生真正的开销时,这种聚合很有用。否则,你不需要它。