在Symfony中,如何在多对多关系中更新反向侧的计数器字段?

在Symfony中,如何在多对多关系中更新反向侧的计数器字段?,symfony,doctrine,many-to-many,sonata-admin,Symfony,Doctrine,Many To Many,Sonata Admin,我有两个enteties User和Category,它们通过多对多关系相互连接 manyToMany: categories: targetEntity: Category joinTable: name: users_categories joinColumns: user_id: referencedColumnName: id inverseJoinColumns:

我有两个enteties User和Category,它们通过多对多关系相互连接

manyToMany:
    categories:
      targetEntity: Category
      joinTable:
        name: users_categories
        joinColumns:
          user_id:
            referencedColumnName: id
        inverseJoinColumns:
          category_id:
            referencedColumnName: id
在my UserAdmin.php(我使用的是Sonata Admin和Sonata用户包)中,它们由以下字段处理:

->add('categories', 'sonata_type_model', array('required' => false, 'expanded' => false, 'multiple' => true, 'label' => 'Chose your categories'))
现在我需要在我的分类实体-user_计数器中添加额外的字段,它存储与它链接的用户数。它应该在用户每次添加、更新或删除其与类别的关系时更新

一个想法是在用户实体中创建一个方法,在保存管理表单之前获取他的类别,将它们与当前输入进行比较,然后做出决策(类别计数器生成+1或-1)。并通过lifecycleCallbacks(prePersist和preUpdate)打开此方法

问题:我的代码将获取所有用户类别,并将它们与每个表单保存时的当前输入进行比较。我怎样才能避免这样的开销?也许这项任务还有其他解决方案


谢谢您的帮助。

您可以跟踪的一种方法是修改实体中的收集方法。例如:

/*
 * @ORM\Column(name="user_counter", type="integer")
 */
 protected $user_counter;

public function addUser(User $user) 
{
    $this->users[] = $user;
    $this->user_counter++;
}

public function removeUser(User $user)
{
    $this->users->remove($user);
    $this->user_counter--;
}
或者,如果不需要数据库中的计数,只需执行$category->getUsers()->count()

编辑:


如果要使用事件侦听器来跟踪此事件,而不是修改实体设置器,请结合使用
$unitOfWork->getScheduledCollectionUpdates()
getDeleteDiff()
getInsertDiff()
。。另一方面,你也应该提高stackoverflow的接受率。谢谢你的链接,Mike。我读了它,如果我意识到一切都是正确的,我不需要在类别中实现这个字段(user\u counter),但应该在类别实体中创建一个getUsersCount方法,该方法将计算这个类别的用户数?然后,当用户在lifecycleCallbacks方法上对其链接类别进行更改时,我应该在我的UserAdmin类中使用此方法?我怎样才能检测到用户在类别中进行了更改?但是如果我的应用程序有一个页面,上面显示了所有类别及其子类别和用户数量,比如:但是如果我的应用程序有一个页面,上面显示了所有类别及其子类别和用户数量,比如:类别1(252)、子类别1(140)等等,该怎么办。本页将有50多个类别。我认为每个类别的count()对于应用程序性能来说都是非常昂贵的。请参阅我的答案。我还在编辑答案,以包含一个原则侦听器替代方案。这里的问题是,我没有在类别实体中与用户交互的方法。在用户实体中设置多对多关系。我想,我应该在AddCategory和removeCategorie中创建这个计数器,并手动更新它?编辑:谢谢你的提示!我会尝试在用户实体中使用它(我想)。是的,你可以。或者只需在category中添加反向关系并添加setter/getter。