我正在尝试找出更新数据库中的非规范化值的最佳过程。
以下是该方案:
Scenario: Update Activity Duration
Given the following Task:
| id | name | duration
| 1 | Task 1 | 0
And the following Activity:
| id | name | startedAt | endedAt | task |
| 1 | Activity 1 | 2013-01-01 12:00 | null | 1 |
When I set "Activity 1" endedAt to "2013-01-01 13:00"
And persist "Activity 1"
Then "Activity 1" duration should be 3600
And "Task 1" duration should be 3600
从数据结构中可以看出Task.duration是Activity.duration的非规范化和。
我正在努力的是何时更新Activity.duration和Task.duration。
可以在setEndedAt方法中计算Activity.duration。
Task.duration有点棘手。我想我需要在修改Activity时重新计算postFlush事件中的Task.duration。我假设它必须是postFlush因为我想在数据库中总结活动持续时间而不是获取所有Task.acitivities并在PHP中循环它们。
此外,我希望能够一次更新多个活动(想一想评论/编辑时间表)。在这种情况下,我认为我需要推迟刷新,因此工作单元包含所有修改过的活动。
文档实际上说:
在EntityManager #flush()结束时调用postFlush。无法在侦听器内安全地调用EntityManager#flush()。
可能会将这种方法统一起来。
建议的解决方案似乎有效吗?我无法看到这种方法可以在preFlush或onFlush中完成,因为持续时间尚未保存到DB。
Cheers Leevi
答案 0 :(得分:0)
你可能会使用onFlush
或preUpdate
,但我觉得这种方法会不必要地将你的域对象与Doctrine结合起来。最好的解决方案是不要使用Doctrine的事件。
在更改startedAt
的{{1}}或endedAt
值之前,您可以从Activity
中减去之前的持续时间,然后重新添加。
Task
当然,考虑到实际情况(没有开始时间,将活动从一个任务转移到另一个任务等),实际实施必须稍微复杂一些。)