原则ORM-事件订阅服务器,用于计算“子实体”的值并将其保留在另一个实体上

我对应该在哪里实现事件订阅器感到困惑(实际上,我什至不确定是否应该改为使用实体监听器)。

因此,我有一个名为ServiceDoctrineEntity的实体,该实体有很多存储设备:

class ServiceDoctrineEntity {

    /**
     * One Service has many storage devices.
     *
     * @OneToMany(targetEntity="ServiceStorageDevicesDoctrineEntity",mappedBy="service",cascade={"all"})
     * @OrderBy({"order" = "ASC"})
     * @var ServiceStorageDevicesDoctrineEntity $storage_devices Description.
     */
    private $storage_devices;
}

每个存储设备都有自己的“存储空间/值”

class ServiceStorageDevicesDoctrineEntity {
    /**
     * @Column(type="bigint",nullable=true,options={"comment":"The normalised value,calculated from $amount * $unit."})
     * @var int $value The normalised value,calculated from $amount * $unit.
     */
    private $value;
}

我的问题是,我应该运行一个计算逻辑,该逻辑将在每次存储设备发生更改(添加/删除新的存储设备或更改存储空间等)时触发。

  1. 我需要计算该服务具有的“存储设备”总数。
  2. 汇总或汇总每个存储设备的总“值”

这些“摘要”将保存在名为ServiceStorageSummaryDoctrineEntity

的实体上
class ServiceStorageSummaryDoctrineEntity {

    /**
     * One Service Support type has One Service.
     *
     * @OneToOne(targetEntity="ServiceDoctrineEntity",inversedBy="storage_summary")
     * @JoinColumn(name="service_id",referencedColumnName="id")
     */
    private $service;

    /**
     * @Column(type="bigint",options={"default":0,"comment":"The total value (normalised) of storage space."})
     * @var integer $total_value The total value (normalised) of storage space.
     */
    private $total_value;

    /**
     * @Column(type="integer","comment":"The total amount of storage devices."})
     * @var integer $device_count The total amount of storage devices.
     */
    private $device_count;

}

我试图为此编写一个EventSubscriber类来监听onFlush事件:

class ServiceStorageDevicesEventListener implements EventSubscriber {

    /**
     * Returns an array of events this subscriber wants to listen to.
     *
     * @return string[]
     */
    public function getSubscribedEvents() {
        return array(
            Events::onFlush,);
    }

    public function onFlush( OnFlushEventArgs $eventArgs ) {
        $em  = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ( $uow->getScheduledEntityInsertions() as $entity ) {
            // Should I run the computation here?
            // Which entity should I be listening to? `ServiceDoctrineEntity` or `ServiceStorageSummaryDoctrineEntity`?
        }

        foreach ( $uow->getScheduledEntityUpdates() as $entity ) {
            // Should I run the computation here?
            // Which entity should I be listening to? `ServiceDoctrineEntity` or `ServiceStorageSummaryDoctrineEntity`?
        }

        foreach ( $uow->getScheduledEntityDeletions() as $entity ) {
            // Should I run the computation here?
            // Which entity should I be listening to? `ServiceDoctrineEntity` or `ServiceStorageSummaryDoctrineEntity`?
        }
    }
}

但是我不确定如何进行此操作

  1. 我可以使用事件订阅服务器吗?
  2. 我有权听onFlush事件
  3. 我应该列出哪个实体:

    (a)ServiceDoctrine实体并遍历每个存储设备?

    (b)还是ServiceStorageDevicesDoctrineEntity,但这是否意味着计算逻辑将针对每个存储设备更改而运行?

linyilun 回答:原则ORM-事件订阅服务器,用于计算“子实体”的值并将其保留在另一个实体上

  

我可以使用事件订阅服务器吗?

是的。如果您想在某个事件发生后执行一些逻辑,那么您来对地方了。

EventSubscriber给您更大的灵活性,因为您可以收听多个教义事件(其中EventListener通常与特定事件相关联)

  

我有权听onFlush事件

onFlush事件发生在所有实体更改集都计算完之后。

由于您要更新相关实体的数据,因此建议您听以下事件:

  • prePersist
  • preUpdate
  • preRemove
  

我应该列出哪个实体

收听ServiceStorageSummaryDoctrineEntity意味着您只要更改此实体即可执行一些操作。但是,由于您永远不会手动更新此实体,因此您的事件将永远不会被触发。

您想做的是,每当ServiceStorageDevicesDoctrineEntity被更改时,都在监视更改。

您的EventListener可能看起来像这样:

class ServiceStorageDevicesEventListener implements EventSubscriber {
    public function getSubscribedEvents() {
        return array(
            Events::prePersist,Events::preUpdate,Events::preRemove,);
    }

    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();

        // don't perform operations for other entities
        if (!$entity instanceof ServiceStorageDevicesDoctrineEntity) {
           return;
        }

        // update your related entity here,ex:
        $entity->getServiceStorageDevices()->getServiceStorageSummary()->setTotalValue(10);
    }

    public function preUpdate(PreUpdateEventArgs $args)
    {
        // ...
    }

    public function preRemove(LifecycleEventArgs $args)
    {
        // ...
    }
}

希望有帮助。

本文链接:https://www.f2er.com/3159440.html

大家都在问