在Doctrine 2(和Symfony)中正确使用$ unitOfWork-> getScheduledCollectionDeletions()是什么?

问题描述 投票:4回答:1

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

如果将新实体添加到关系中或更新关系(始终保持元素),我可以使用$unitOfWork->getScheduledCollectionUpdates()检测更改,然后检查getInsertDiff()getDeleteDiff()。到现在为止还挺好。

当我从关系中取出所有实体时出现问题:“之前有两个相关实体,但现在没有相关实体。”

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

  • getDeleteDiff()这个系列并没有说什么。
  • getSnapshot()没有告诉我之前有哪些实体

我怎么知道哪些实体被从多对多关系中取出?


我添加了一个完整实现的Gist:一切正常(可能需要一些优化),除了$uow->getScheduledCollectionDeletions()(第101行)

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

symfony doctrine-orm doctrine
1个回答
6
投票

造成这个问题的原因有两个:

1)当在clear()上调用方法Doctrine\ORM\PersistentCollection时,它将:

  1. 清除其内部实体集合。
  2. scheduleCollectionDeletion()上打电话给Doctrine\ORM\UnitOfWork
  3. 拍摄自己的新快照。

2号是你的收藏品出现在$uow->getScheduledCollectionDeletions()(而不是$uow->getScheduledCollectionUpdates())的原因。数字3是您在清除之前无法确定集合中的内容的原因。

2)当使用Symfony2 Form组件,特别是ChoiceTypeCollectionType类型与multiple选项组合时,当从集合中删除所有实体时,将调用clear()方法。

这是因为MergeDoctrineCollectionListener在这里添加:https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php#L55

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

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

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

2)重新设计你的计数器:也许还要听OnLoad事件,它可以计算从数据库中提取时集合中实体的数量。这样你的OnFlush监听器就可以使用该数字来知道清除时从集合中删除了多少个实体。

© www.soinside.com 2019 - 2024. All rights reserved.