2013-03-09 42 views
4

我試圖在onFlush事件中檢測到多對多關係的更改。

如果將新實體添加到關係或更新關係(始終保留元素),我可以使用$unitOfWork->getScheduledCollectionUpdates()檢測更改,然後檢查getInsertDiff()getDeleteDiff()。到現在爲止還挺好。

問題是當我把所有的實體出來的關係:「有兩個相關的實體之前,但也有NO相關實體現在。」

當關係爲空我可以訪問$unitOfWork->getScheduledCollectionDeletions(),但沒有辦法知道哪些實體被刪除:

  • getDeleteDiff()這個集合並沒有告訴任何東西。
  • getSnapshot()並沒有告訴我哪些實體有

我怎麼知道採取哪些實體了許多一對多關係的前?


我添加了一個要點全面實施:一切工作正常(它可能需要一些優化),除了$uow->getScheduledCollectionDeletions()(線101)

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

+0

'$ uow-> getScheduledCollectionUpdates()'和'$ uow-> getScheduledCollectionDeletions()'都返回集合數組。而且這些集合的行爲與它們的使用位置無關。 你究竟想要完成什麼?看起來你想用「插入/刪除/刪除__」中的_entities來「做些什麼」。如果這是真的,那麼你只需要'$ uow-> getScheduledEntityInsertions()'(它將包含將被插入的_all_實體)和'$ uow-> getScheduledEntityDeletions()'(將包含將被刪除的_all_實體) 。 – 2013-03-12 19:42:45

+0

插入/刪除的唯一其他_rows_是連接表(多對多關聯)的那些,但這些是_not_實體。 – 2013-03-12 19:43:23

+0

我想要做的是保持COUNTER更新。你可以在Gist的代碼中看到它。基本上說:我有一個帶有相關標籤(多對多)和用戶(多對一)模型的Post模型。我不能控制的唯一情況是我刪除了Post之前的所有標籤。這個「已刪除的行/實體」應該在'$ uow-> getScheduledCollectionDeletions()'中註冊,但我找不到任何對已刪除標籤的引用。我確信解決方案非常簡單,但我無法在網上找到任何文檔... – eillarra 2013-03-13 08:14:43

回答

6

原因該問題有兩方面:

1)當方法在Doctrine\ORM\PersistentCollection上調用時,它將:

  1. 清除其實體的內部集合。
  2. 致電scheduleCollectionDeletion()關於Doctrine\ORM\UnitOfWork
  3. 拍攝自己的新快照。

2號是您的收藏出現在$uow->getScheduledCollectionDeletions()(而不是在$uow->getScheduledCollectionUpdates())中的原因。 3號是您清除之前無法確定收集內容的原因。

2)當使用Symfony2的Form組件,特別是ChoiceTypeCollectionType類型與選項multiple組合,當所有實體應該從集合中移除clear()方法將被調用。

這是由於其在這裏添加MergeDoctrineCollectionListenerhttps://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php#L55

這是因爲做了優化:它的速度更快這種方式來清除集合,在檢查該實體應當從它刪除代替。

我能想到兩個可能的解決方案

1)創建一個叉symfony/symfony和實施,以選項不添加MergeDoctrineCollectionListener。也許像no_clear,以防止添加偵聽器。這不會引入BC中斷,並且可以解決您的問題,因爲所有實體都應該被刪除,因此集合的clear()方法將不會被調用。

2)重新設計您的計數器:也許還會收聽OnLoad事件,該事件可以從數據庫中提取集合中的實體數量。這樣你的OnFlush監聽器就可以使用這個數字來知道清除後從集合中刪除了多少個實體。

+0

這就是我的想法:'$ uow-> getScheduledCollectionUpdates()'管理着所有事情,但不是那樣的。在我的代碼中可能有些問題,但是這是它的表現:a)通過'$ collection-> getInsertDiff()'檢測到新的插入; b)刪除**,只要至少有一個元素留在關係**中,可以通過$ collection-> getDeleteDiff()來檢測;但是c)如果所有元素都從關係中獲取(例如,所有標籤都被刪除了),那麼'$ uow-> getScheduledCollectionUpdates()'**爲空**。 – eillarra 2013-03-13 20:11:47

+0

對於c)'$ uow-> getScheduledCollectionDeletions()**存在**,但我不知道在哪裏查找有關已刪除實體的信息。 '$ collection-> toArray()**在這種情況下爲空**。 – eillarra 2013-03-13 20:19:38

+0

你能分享從集合中刪除標籤的所有代碼嗎?或者也許更好:完整的郵政實體? – 2013-03-13 21:30:04

相關問題