symfony 教义事件:如何跟踪对ManyToMany集合的添加/移除?

deikduxw  于 2023-01-31  发布在  其他
关注(0)|答案(2)|浏览(88)

我有一个Application实体,它与SortList实体有ManyToMany关系。拥有方是Application。有一个简单的连接表为这个关系创建Map。
下面是Application实体在管理集合方面的外观:

/**
 * Add sortLists
 *
 * @param \AppBundle\Entity\SortList $sortList
 * @return Application
 */
public function addSortList(SortList $sortList)
{
    $this->sortLists[] = $sortList;
    $sortList->addApplication($this);

    return $this;
}

/**
 * Remove sortLists
 *
 * @param \AppBundle\Entity\SortList $sortList
 */
public function removeSortList(SortList $sortList)
{
    $this->sortLists->removeElement($sortList);
    $sortList->removeApplication($this);
}

/**
 * Get sortLists
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getSortLists()
{
    return $this->sortLists;
}

我希望跟踪何时在Application中添加或删除SortLists

我已经知道我不能使用postUpdate生命周期事件来跟踪这些变更集合。
相反,我似乎应该使用onFlush,然后使用$unitOfWork->getScheduledCollectionUpdates()$unitOfWork->getScheduledCollectionDeletions()
对于更新,我可以使用“internal”方法getInsertDiff来查看集合中添加了哪些项,使用getDeleteDiff来查看集合中删除了哪些项。
但我有几点担心:
1.如果集合中的所有项都被删除了,则无法查看实际删除了哪些项,因为$unitOfWork->getScheduledCollectionDeletions()没有此信息。
1.我使用的方法被标记为“内部”;看起来它们可能会在未来的某个时候“消失”或者被重构而不让我知道?

6uxekuva

6uxekuva1#

我在https://stackoverflow.com/a/75277337/5418514中解决了这个空的getDeleteDiff
这个数据有时候是空的,这是一个老问题,但现在仍然存在。目前的解决办法是自己重新获取数据。

public function onFlush(OnFlushEventArgs $args)
{
    $uow = $args->getEntityManager()->getUnitOfWork();
    
    foreach ($uow->getScheduledCollectionDeletions() as $collection) {
        /**
         * "getDeleteDiff" is not reliable, collection->clear on PersistentCollection also clears the original snapshot
         * A reliable way to get removed items is: clone collection, fetch original data
         */
        $removedData = $collection->getDeleteDiff();
        if (!$removedData) {
            $clone = clone $collection;
            $clone->setOwner($collection->getOwner(), $collection->getMapping());
            // This gets the real data from the database into the clone
            $uow->loadCollection($clone);

            // The actual removed items!
            $removedData = $clone->toArray();
        }
    }
}
lkaoscv7

lkaoscv72#

我认为下面的例子涵盖了你所需要的一切,所以你只需要在你的应用程序中实现你想要/需要的东西。

that website中有许多其他有用的监听器示例,所以只需使用listener关键字的搜索功能。有一次我做了与您相同的事情,但无法找到M-N关联的示例。如果我可以,我会发布它,但不确定我是否可以!

相关问题