2017-10-06 31 views
0

这个问题可能与开发本身更多地涉及体系结构和应用程序设计。这里有云:从DB数据计算的实体属性

我有日期和会议(上午或下午)定义的实体,我需要一个get/set属性知道isReservedAllDay(),这意味着,该实体拥有保留一个免费的实体在同一天,但不同的会议。

<?php 

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

class HallReservation 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var \Date 
    * 
    * @ORM\Column(name="date", type="date") 
    */ 
    private $date; 

    /** 
    * @var string: "AM" | "PM" 
    * 
    * @ORM\Column(name="session", type="string") 
    */ 
    private $session; 

isReservedAllDay()getReservedAllDay()实际上是通过访问数据库,它当然应该是出于一个实体的范围和在控制器或服务进行设置。

我的第一个解决方案就是这样做的,在控制器查询到设置去属性,然后能够得到上树枝,形式或任何该属性值,而没有坚持,甚至映射这种性质,本从架构的角度来看可能是一个合适的解决方案(或者可能不是!),但从开发的角度来看并不好,因为它迫使我每次获得实例时都要设置属性。

function setReservedAllDay($reserved) 
{ 
    $this->reservedAllDay = $reserved; 
    return $this; 
} 

function getReservedAllDay() 
{ 
    return $this->reservedAllDay; 
} 

你可以批评这种方法或建议更好的吗?

谢谢

+0

是否有你不想在数据库中将其作为布尔值持久化的原因?这对我来说似乎是一个宝贵的价值。 – ASOlivieri

+0

原因是:这是一个计算字段,我更喜欢每次需要“计算”时使用它,而不是每次需要使用它时,我每次删除一个预留时都必须查询和修改该字段(此方法不易出错) –

+1

只需以更自动的方式做你想做的事情:使用postLoad原则监听器(将事件调度器注入到此事件中),然后如果加载了'HallReservation',则通过调度器分派自定义事件(将实体保存为有效载荷)与另一位该自定义事件的监听者一起执行您的逻辑并设置其值。这样你就不需要在控制器中手动调用它。自定义事件是必需的,因为您无法将实体管理器注入到doctrine事件侦听器(循环依赖性问题)中。这应该是一种方式去 – Joe

回答

1

通过主义听众例如设定值。 刚刚复制/键入这个,所以它可能不会完全正常工作,但你应该明白了。 也许这种方法将涵盖您的需求。

编辑:像ccKep提到的那样,entityManager已经可以通过postLoad函数中的LifecycleEventArgs直接获得。如果你需要另一个依赖于entityManager的服务,并且不能直接注入,那么只需要添加自定义事件。 我会将代码保持不变,也许对其他人有用(他需要的不仅仅是entityManager)。

教义听众:

class HallReservationLoadListener 
{ 
    /** @var EventDispatcherInterface */ 
    protected $eventDispatcher; 

    public function __construct(EventDispatcherInterface $eventDispatcher) 
    { 
     $this->eventDispatcher = $eventDispatcher; 
    } 

    /** 
    * 
    * @param LifecycleEventArgs $args 
    */ 
    public function postLoad(LifecycleEventArgs $args) 
    { 
     $item = $args->getEntity(); 
     if($item instanceof HallReservation) { 
      $event = new HallReservationLoadedEvent($item); 
      $this->eventDispatcher->dispatch(HallReservationLoadedEvent::NAME, $event); 
     } 

    } 
} 

自定义事件:

class HallReservationLoadedEvent extends Event 
{ 
    const NAME = 'hallreservation.loaded'; 

    protected $hallreservation; 

    public function __construct(HallReservation $hallreservation) 
    { 
     $this->hallreservation = $hallreservation; 
    } 

    public function getHallreservation() 
    { 
     return $this->hallreservation; 
    } 
} 

您的自定义事件监听器:

class HallReservationReservedListener 
{ 
    protected $entityManager; 

    public function __construct(EntityManagerInterface $entityManager) 
    { 
     $this->entityManager = $entityManager; 
    } 

    public function setReservedProperty(HallReservationLoadedEvent $event) 
    { 
     $hallreservation = $event->getHallreservation(); 
     //do your stuff 
    } 
} 

服务的定义:

app.listener.hallreservationload: 
     class: AppBundle\Listener\HallReservationLoadListener 
     arguments: ['@event_dispatcher'] 
     tags: 
      - { name: doctrine.event_listener, event: postLoad } 
    app.listener.hallreservationload.reservedproperty: 
     class: AppBundle\Listener\HallReservationReservedListener 
     arguments: ['@doctrine.orm.entity_manager'] 
     tags: 
      - { name: kernel.event_listener, event: 'hallreservation.loaded', method: 'setReservedProperty'}