Symfony Entity加载计算字段但不总是

时间:2016-11-06 18:18:40

标签: symfony entity

我有一个没有映射计算字段的symfony实体

namespace AppBundle\Entity;

class Page
{

     /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * Page count. Non-mapped
     *
     * @var integer
     */
    protected $pageCount;

}

$ pageCount值可以通过使用一个远程服务来获得,该服务将提供在应用程序中使用的值。

我认为最好的方法是使用postLoad事件来处理这个问题。

class PageListener
{
    /**
     * @ORM\PostLoad
     */
    public function postLoad(LifecycleEventArgs $eventArgs)
    {
       // ...
    }
}

我需要在加载值时检索此值。

public function indexAction()
{
    // I want to fetch the pageHits here
    $pagesListing = $this->getDoctrine()
        ->getRepository('AppBundle:Pages')
        ->findAll();

    // I don't want to fetch the pageHits here
    $pagesListing2 = $this->getDoctrine()
        ->getRepository('AppBundle:Pages')
        ->findAll();

 }

但是,这将始终导致对远程服务的调用。 在某些情况下,我可能不希望调用该服务,从而降低了应用程序的性能负担。

如何自动获取远程值,但仅限于我想要的时候。

1 个答案:

答案 0 :(得分:3)

你的“问题”很常见,也是我从不直接使用Doctrine存储库的原因之一。

解决方案我建议

始终制作自定义存储库服务并将Doctrine注入其中。

这样,如果你想合并一些其他数据源的数据(例如 Redis 文件系统某些远程API ) ,你可以完全控制它并封装进程。

示例:

class PageRepository
{
    private $em;
    private $api;

    public function __construct(EntityManagerInterface $em, MyAwesomeApi $api)
    {
        $this->em = $em;
        $this->api = $api;
    }

    public function find($id)
    {
        return $em->getRepository(Page::class)->find($id);
    }

    public function findAll()
    {
        return $em->getRepository(Page::class)->findAll();
    }

    public function findWithCount($id)
    {
        $page = $this->find($id);
        $count = $this->myAwesomeApi->getPageCount($id);

        return new PageWithCount($page, $count);
    }
}

解决方案我不推荐,但有效:)

如果您不想更改代码结构并希望保持原样,那么您可以进行一项非常简单的更改,只有在必要时才会加载pageCount:

将代码从Page :: postLoad方法移到Page :: getPageCount()

示例:

public function getPageCount()
{
    if (null === $this->pageCount) {
        $this->pageCount = MyAwesomeApi::getPageCount($this->id);
    }
    return $this->pageCount;
}

这样,只有在某些东西试图访问它时才会加载pageCount