【问题标题】:Add entities to Unit of Work将实体添加到工作单元
【发布时间】:2018-09-13 03:27:17
【问题描述】:

我有一个实体被持久化,在某些情况下需要创建其他实体并与之一起持久化。

当前的用例是在 EasyAdminBundle 的列表视图中切换布尔属性时,如果该属性设置为 true,我需要创建实体并保留它们。

我想在preUpdate事件中做,所以我看了一下工作单元界面并试图理解它。

我可以访问以下方法:

$event->getEntityManager()->getUnitOfWork()->getScheduledEntityUpdates()

$event->getEntityManager()->getUnitOfWork()->getScheduledEntityInsetions()

因此,我转储了这些内容并获得了 1 个实体条目以更新,并为插入获得了空数组。

然后添加新实体:

$entity = new Entity();
$event->getEntityManager()->getUnitOfWork()->scheduleForInsert($entity);

毕竟我再次转储了计划更新和插入的实体,并且一切都正确。

array:1 [▼
  "000000006b3c425d000000005d5d714c" => Entity {#1045 ▶}
]

插入计划中此实体的数组键与更新计划中的特征相同。

很遗憾,没有执行插入查询。

有没有办法(乍一看)将对象添加到当前工作单元,以便修改数据以更新/保留在 preUpdate 事件中?

编辑(侦听器代码):

/**
     * @param Market $market
     * @param LifecycleEventArgs $event
     * @throws \Doctrine\ORM\ORMException
     */
    public function preUpdate(Market $market, LifecycleEventArgs $event)
    {
        $uow = $event->getEntityManager()->getUnitOfWork();
        $changeset = $event->getEntityManager()->getUnitOfWork()->getEntityChangeSet($market);

        if(isset($changeset['boolean_field']) && count($changeset['boolean_field']) == 2){
            if(!$changeset['boolean_field'][1]){//THIS IS NO CONCERN AT THE MOMENT
                $activations = $event->getEntityManager()->getRepository('BaseMapping:MarketWatchedByUser')
                    ->findBy(['market' => $market]);

                foreach ($activations as $a) {
                    $event->getEntityManager()->remove($a);
                }
            }
            else{//THIS IS WHAT IS BEING TESTED
                $users = $event->getEntityManager()->getRepository('UserBundle:User')
                    ->findAll();

                foreach ($users as $u) {
                    $activation = new MarketWatchedByUser();
                    $activation->setUser($u);
                    $activation->setMarket($market);
                    dump($event->getEntityManager()->getUnitOfWork()->isScheduledForInsert($activation));
                    $event->getEntityManager()->getUnitOfWork()->scheduleForInsert($activation);
                    dump($event->getEntityManager()->getUnitOfWork()->isScheduledForInsert($activation));
                }
                $event->getEntityManager()->getUnitOfWork()->commit();//ENDLESS LOOP
                dump($event->getEntityManager()->getUnitOfWork()->getScheduledEntityUpdates());
                dump($event->getEntityManager()->getUnitOfWork()->getScheduledEntityInsertions());
            }
        }
    }

【问题讨论】:

  • 现在,我们知道了更多。答案是,你不应该那样做。 preUpdate 不允许进行此类操作检查 (docs.doctrine-project.org/projects/doctrine-orm/en/latest/…)。为什么不在 Model/Handler/ 中做这个操作?
  • 因为逻辑是由easyadminbundle实现的,我想避免覆盖它的控制器。基本上,当我从列表视图切换一个属性(实体得到更新)时,我需要代码已执行(和正在创建的实体)@mleko
  • 我会选择自定义操作
  • @mleko 如果您想争论并建立答案,我很乐意接受。或者我可以做到。我错过了我试图做的事情在教义中是不允许的这一点。我被工作单元界面误导了

标签: php doctrine-orm


【解决方案1】:

实体侦听器中不允许您尝试执行的操作,preUpdate 尤其具有限制性。

这看起来也像业务逻辑。我建议将逻辑移至模型/处理程序。

您可以尝试添加 custom action 以不必在 EasyAdminBundle 内部摆弄。

【讨论】:

    猜你喜欢
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多