本文介绍了在 Doctrine 2(和 Symfony)中正确使用 $unitOfWork->getScheduledCollectionDeletions() 是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试检测 onFlush 事件中多对多关系的变化.

I'm trying to detect changes in a many-to-many relation in an onFlush event.

如果将新实体添加到关系或更新关系(始终保留一个元素),我可以使用 $unitOfWork->getScheduledCollectionUpdates() 检测更改,然后检查 getInsertDiff()getDeleteDiff().到目前为止一切顺利.

If new entities are added to the relation or the relation is updated (always keeping an element), I can detect changes using $unitOfWork->getScheduledCollectionUpdates() and then check for getInsertDiff() or getDeleteDiff(). So far so good.

当我从关系中取出所有实体时,问题出现了:之前有两个相关实体,但现在有 NO 个相关实体."

The problem comes when I take all the entities out of the relation: "There were two related entities before but there are NO related entities now."

当关系为空时,我可以访问 $unitOfWork->getScheduledCollectionDeletions(),但无法知道删除了哪些实体:

When the relation is left empty I can access $unitOfWork->getScheduledCollectionDeletions(), but there is no way of knowing which entities were deleted:

    此集合的
  • getDeleteDiff() 没有任何意义.
  • getSnapshot() 没有告诉我之前有哪些实体
  • getDeleteDiff() for this collections doesn't tell anything.
  • getSnapshot() doesn't tell me which entities were there before

我应该如何知道从多对多关系中取出了哪些实体?

How should I know which entities were taken out of the many-to-many relation?

我添加了一个完整实现的要点:除了 $uow->getScheduledCollectionDeletions() (第 101 行)

I've added a Gist with the full implementation: everything works ok (it may need some optimization) except $uow->getScheduledCollectionDeletions() (line 101)

https://gist.github.com/eillarra/5127606

推荐答案

这个问题的原因是双重的:

1) 当在 DoctrineORMPersistentCollection 上调用方法 clear() 时,它将:

1) When the method clear() is called on a DoctrineORMPersistentCollection, it will:

  1. 清除其内部实体集合.
  2. DoctrineORMUnitOfWork 上调用 scheduleCollectionDelection().
  3. 为自己拍摄一张新的快照.

第二个原因是您的收藏出现在 $uow->getScheduledCollectionDeletions() 中(而不是在 $uow->getScheduledCollectionUpdates() 中).第 3 点是您无法确定收藏品在被清除之前包含哪些内容的原因.

Number 2 is the reason your collection shows up in $uow->getScheduledCollectionDeletions() (and not in $uow->getScheduledCollectionUpdates()). Number 3 is the reason why you cannot determine what was in the collection before it was cleared.

2) 当使用 Symfony2 表单组件时,特别是 ChoiceTypeCollectionType 类型与选项 multiple 组合时,所有 实体应该从集合中移除时,将调用 clear() 方法.

2) When using the Symfony2 Form component, specifically the ChoiceType or CollectionType types in combination with the option multiple, that clear() method will get called when all entities should be removed from the collection.

这是由于在此处添加的 MergeDoctrineCollectionListener 造成的:https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php#L55

This is due to the MergeDoctrineCollectionListener which is added here:https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php#L55

这是作为优化完成的:以这种方式清除集合更快,而不是检查应该从中删除哪些实体.

This is done as optimization: It's faster to clear a collection this way, in stead of checking which entities should be removed from it.

我能想到两个可能的解决方案:

1) 创建一个分支 symfony/symfony 并实现一个选项以便添加 MergeDoctrineCollectionListener.也许像 no_clear 之类的东西可以防止添加侦听器.这不会引入 BC 中断,并且会解决您的问题,因为当应该删除 所有 实体时,不会调用集合的 clear() 方法.

1) Create a fork symfony/symfony and implement an option in order to not add the MergeDoctrineCollectionListener. Maybe something like no_clear to prevent the listener from being added. This won't introduce a BC break and would solve your problem because the clear() method of a collection won't get called when all entities should be removed.

2) 重新设计您的计数器:也许还可以监听 OnLoad 事件,该事件可以在从数据库中获取集合时计算集合中的实体数量.这样,您的 OnFlush 侦听器可以使用该数字来了解在清除集合时从集合中删除了多少实体.

2) Redesign your counter: Maybe also listen to the OnLoad event which can count the amount of entities in the collection at the time it's fetched from the db. That way your OnFlush listener can use that number to know how many entities where removed from the collection when it was cleared.

这篇关于在 Doctrine 2(和 Symfony)中正确使用 $unitOfWork->getScheduledCollectionDeletions() 是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 10:14