原则:在插入其他表时更新列


Doctrine: update column on insert in other table

我有两个实体:Service和Session,它们具有一对多的关系

 class Service{
     /**
      * @var int
      *
      * @ORM'Column(name="avg_score", type="integer")
      */
     private $avgScore;
     /**
      * @ORM'OneToMany(targetEntity="Session", mappedBy="service")
      */
      private $sessionList;
 }
 class Session{
      /**
       * @ORM'ManyToOne(targetEntity="Service", inversedBy="sessionList")
       * @ORM'JoinColumn(name="service_id", referencedColumnName="id")
       */
      private $service;
       /**
        * @var int
        *
        * @ORM'Column(name="score", type="integer", nullable=true)
        */
        private $score;
 }

与Doctrine QueryBuilder我怎么能更新Service实体的$avgScore每次新的Session$score被创建?

这就是我想做的:

   $qb = $this->getDoctrine()->getEntityManager()->createQueryBuilder();
    $q = $qb->update('AppBundle:Service', 's')
        ->join('AppBundle:Session', 'ss')
        ->addSelect('avg(ss.score) as score_avg')
        ->groupBy('ss.service')
        ->set('s.avgScore', 'score_avg')
        ->where('s.id = ?1')
        ->setParameter(1, $service->getId())
        ->getQuery();
    $q->execute();

您需要创建一个Doctrine事件监听器

services:
    my.listener:
        class: AppBundle'EventListener'AvgScoreUpdater
        tags:
            - { name: doctrine.event_listener, event: prePersist }

然后在AvgScoreUpdater实现逻辑:

class AvgScoreUpdater
{
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if (!($entity instanceof Session) || !$entity->getScore()) {
            return;
        }
        $entityManager = $args->getEntityManager();
        $service = $entity->getService();
        // Then realize logic to update avg_score on a service
    }
}