symfony3 doctrine2 association counter field

时间:2016-09-10 15:37:00

标签: symfony doctrine-orm associations doctrine-extensions

请考虑以下情况:我有两个实体:ArticleArticleComment

// \AppBundle\Entity\Article

/**
 * @ORM\OneToMany(targetEntity="ArticleComment", mappedBy="article")
 */
private $comments;

我需要在文章的字段中存储评论数量(例如articles.comments_count)。每当创建或删除评论时,都需要更新该字段。

以前我使用了内置CounterCache behavior的CakePHP框架,它自动执行此操作。我已经尽力为Doctrine 2找到类似的东西(从DoctrineExtensions库开始),但似乎没有什么可以做我正在寻找的东西。

任何执行此操作的库?或者我必须提出自己的解决方案吗?

编辑:我尝试使用Entity Events,但我在许多实体上需要这种行为,所以我对可重用的解决方案感兴趣

2 个答案:

答案 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查询计算的聚合。 当你有很多连接的实体在计算过程中产生真正的开销时,这种聚合很有用。否则,你不需要它。