Doctrine2 延迟加载

Doctrine2 Lazy Loading

我正在阅读 Doctrine 2 中的惰性关联以及如何避免以下情况:

文档中的 paragraph 解释了如何为您的实体启用惰性关联。我不知道如何在我的实体存储库中使用它。

到目前为止,我尝试对实体存储库进行一些调整,但没有成功。我也试过 this post, this post and this post 但他们似乎可以处理 ManyToMany 或其他完全不同的情况。

有人可以解释如何以及在何处使用惰性关联来避免上述示例吗?

由于长度原因,不相关的私有属性和 getters/setters 已从此代码片段中删除。

src/AppBundle/Entity/News.php

class News
{
    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Account", fetch="EXTRA_LAZY")
     * @ORM\JoinColumn(name="author", referencedColumnName="id")
     */
    private $author;
}

src/AppBundle/Entity/Repositories/NewsRepository.php

class NewsRepository extends EntityRepository
{
    /**
     * @param $id
     * @return mixed
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function findOneById($id) {
        return $this->createQueryBuilder('a')
                    ->andWhere('a.id = :id')
                    ->setParameter('id', $id)
                    ->getQuery()
                    ->getOneOrNullResult();
    }
}

src/AppBundle/Controller/NewsController.php

/**
 * @Route("/{id}", name="news_item")
 * @Method({"GET"})
 * @Template("AppBundle:news:item.html.twig")
 */
public function articleAction(Request $request, $id)
{
    $news_item = $this->getDoctrine()->getRepository('AppBundle:News')->findOneById($id);

    if (!$news_item) {
        throw $this->createNotFoundException('No news item found by id ' . $id);
    }

    return array(
        'news_item' => $news_item
    );
}

src/AppBundle/Resources/views/news/item.html.twig

{% extends 'base.html.twig' %}

{% block body %}
    {{ dump(news_item) }} }}
{% endblock %}

您无需执行任何特殊操作即可启用延迟加载。您显示的关系中的额外延迟加载对于新闻不加载作者不是必需的。这只是意味着您可以在集合上进行类似 ->contains 的调用,而无需加载整个集合以及其他一些便利。

dump() 应该在 Author 上显示如下内容:

protected 'author' => 
    object(Proxies\__CG__\YourNamespace\YourBundle\Entity\Author)

这并不意味着实体已从数据库中获取。引用 the docs.

Instead of passing you back a real Author instance and a collection of comments Doctrine will create proxy instances for you. Only if you access these proxies for the first time they will go through the EntityManager and load their state from the database.

如果您没有取回代理 class,可能是因为您已经在代码的前面访问了该关系。或者您已在查询中明确获取该实体。