根据数据库数据计算的实体 属性
Entity property calculated from DB data
这个问题可能与架构和应用程序设计有关,而不是与开发本身有关。开始了:
我有一个用日期和会话(AM 或 PM)定义的实体,我需要一个 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()其实是访问数据库设置的,当然应该不在实体并在控制器或服务中完成。
我的第一个解决方案是这样做,在控制器中查询 set de 属性 然后能够 get 这个 属性 值在树枝、表单或任何地方,没有坚持甚至映射这个 属性,从架构的角度来看这可能是一个合适的解决方案(或者可能不是!)但从开发的观点,因为它迫使我每次获得实例时都设置 属性。
function setReservedAllDay($reserved)
{
$this->reservedAllDay = $reserved;
return $this;
}
function getReservedAllDay()
{
return $this->reservedAllDay;
}
您能否批评这种方法或提出更好的方法?
谢谢
例如通过学说侦听器设置值。
只需将 copied/typed 放在一起,因此它可能无法完全正常工作,但您应该明白了。
也许这种方法可以满足您的需求。
编辑:就像 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'}
这个问题可能与架构和应用程序设计有关,而不是与开发本身有关。开始了:
我有一个用日期和会话(AM 或 PM)定义的实体,我需要一个 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()其实是访问数据库设置的,当然应该不在实体并在控制器或服务中完成。
我的第一个解决方案是这样做,在控制器中查询 set de 属性 然后能够 get 这个 属性 值在树枝、表单或任何地方,没有坚持甚至映射这个 属性,从架构的角度来看这可能是一个合适的解决方案(或者可能不是!)但从开发的观点,因为它迫使我每次获得实例时都设置 属性。
function setReservedAllDay($reserved)
{
$this->reservedAllDay = $reserved;
return $this;
}
function getReservedAllDay()
{
return $this->reservedAllDay;
}
您能否批评这种方法或提出更好的方法?
谢谢
例如通过学说侦听器设置值。 只需将 copied/typed 放在一起,因此它可能无法完全正常工作,但您应该明白了。 也许这种方法可以满足您的需求。
编辑:就像 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'}