【问题标题】:Doctrine2 doesn't load Collection until a method is called在调用方法之前,Doctrine2 不会加载 Collection
【发布时间】:2013-01-11 09:59:38
【问题描述】:

Doctrine2 何时加载 ArrayCollection?
直到我调用一个方法,比如 count 或 getValues,我都没有数据
这是我的情况。我有一个与促销实体具有 OneToMany(双向)关系的委托实体,如下所示:

Promotion.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Promotion
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Delegation", inversedBy="promotions", cascade={"persist"})
     * @ORM\JoinColumn(name="delegation_id", referencedColumnName="id")
     */
    protected $delegation;
}

Delegation.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Delegation
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Promotion", mappedBy="delegation", cascade={"all"}, orphanRemoval=true)
     */
    public $promotions;

    public function __construct() {
        $this->promotions = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

现在我执行以下操作(使用给定的委托)

$promotion = new Promotion();
$promotion = new Promotion();
$promotion->setDelegation($delegation);
$delegation->addPromotion($promotion);

$em->persist($promotion);
$em->flush();

在数据库中查找关系是可以的。我的促销行的delegation_id 设置正确。
现在我的问题来了:如果我要求 $delegation->getPromotions() 我得到一个空的 PersistenCollection,但如果我要求一个集合的方法,比如 $delegation->getPromotions()->count(),一切都是好的,从这里开始。我得到正确的号码。现在询问 $delegation->getPromotions() 之后我也正确获得了 PersistenCollection。
为什么会这样? Doctrine2 什么时候加载 Collection?

例子:

$delegation = $em->getRepository('Bundle:Delegation')->findOneById(1);
var_dump($delegation->getPromotions()); //empty
var_dump($delegation->getPromotions()->count()); //1
var_dump($delegation->getPromotions()); //collection with 1 promotion

我可以直接要求promotions->getValues(),然后就可以了,但我想知道发生了什么以及如何解决它。

正如flu 解释here Doctrine2 几乎在任何地方都使用代理类进行延迟加载。但是访问 $delegation->getPromotions() 应该会自动调用相应的 fetch。
var_dump 获取一个空集合,但在 foreach 语句中使用它,例如,它工作正常。

【问题讨论】:

    标签: collections doctrine-orm load lazy-evaluation arraycollection


    【解决方案1】:

    调用$delegation->getPromotions() 只会检索未初始化的Doctrine\ORM\PersistentCollection 对象。该对象不是代理的一部分(如果加载的实体是代理)。

    请参阅Doctrine\ORM\PersistentCollection 的 API 以了解其工作原理。

    基本上,集合本身又是一个真正包装的ArrayCollection 的代理(在这种情况下为值持有者),在调用PersistentCollection 上的任何方法之前,它一直为空。此外,ORM 会尝试优化您的集合被标记为 EXTRA_LAZY 的情况,以便即使您对其应用某些特定操作(如删除或添加项目)也不会加载它。

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 2021-02-25
      • 2013-05-29
      • 2014-09-03
      • 2020-12-17
      • 1970-01-01
      • 2023-04-08
      • 2018-05-16
      相关资源
      最近更新 更多