2017-10-06 36 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'}