在调用方法之前,Doctrine2不会加载Collection

hos*_*eio 4 collections load lazy-evaluation arraycollection doctrine-orm

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;
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我做类似以下的事情(使用给定的委托)

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

$em->persist($promotion);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

寻找与数据库的关系是好的.我有我的促销行,deleg_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
Run Code Online (Sandbox Code Playgroud)

我可以直接询问促销 - > getValues(),并把它搞定,但我想知道发生了什么以及如何解决它.

正如流感在这里解释的那样, Doctrine2几乎在任何地方都使用Proxy类进行延迟加载.但是访问$ delegation-> getPromotions()应该自动调用相应的fetch.
var_dump得到一个空集合,但是在foreach语句中使用它 - 例如 - 它正常工作.

Ocr*_*ius 5

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

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

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