在foreach期间阻止学说/Symfony加载关联的实体?(没有发生延迟加载) [英] Stop Doctrine / Symfony from loading associated entities during foreach? (lazy loading not happening)

查看:51
本文介绍了在foreach期间阻止学说/Symfony加载关联的实体?(没有发生延迟加载)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到该理论会生成其他查询来加载我不直接访问的实体.我以为延迟加载意味着这些关联实体不会被加载.您能帮我弄清楚为什么发生查询以及如何停止查询吗?

I'm seeing doctrine generating additional queries to load entities that I'm not directly accessing. I thought that lazy loading meant these associate entities wouldn't get loaded. Can you help me figure out why the queries are happening and how to stop them?

以下是相关实体:

class Invoice
{
    /**
    * @ORM\OneToMany(targetEntity="InvoiceCard", mappedBy="invoice")
    */
    protected $cards;

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

    /**
     * @var integer
     *
     * @ORM\ManyToOne(targetEntity="Invoice", inversedBy="cards")
     * @ORM\JoinColumn(name="invoice_id", referencedColumnName="id")
     */
    protected $invoice;

    /**
     * @var integer
     *
     * @ORM\ManyToOne(targetEntity="Printing")
     * @ORM\JoinColumn(name="printing_id", referencedColumnName="id")
     */
    protected $printing;

    ...
}
class InvoiceCard extends BaseInvoiceCard{ ... }
class Printing{ ... }

此行代码不会对InvoiceCards表产生任何查询:

This line of code doesn't cause any queries to the InvoiceCards table:

$cards = $invoice->getCards();

一旦我这样做:

foreach($cards as $card){
    //do nothing in this loop
}

我得到一个"SELECT ... FROM invoicecard",这是预期的.

I get a "SELECT ... FROM invoicecard", which is expected.

但是,对于$ cards中的每个$ card,我也都得到了一个"SELECT ... FROM printing".我从不叫$ card-> getPrinting().即使我在循环中什么也不做,也会发生这种情况.只是运行它会导致学说运行这些查询.

However, I'm also getting a "SELECT ... FROM printing" for every $card in $cards. I never call $card->getPrinting(). This happens even if I do nothing at all inside the loop; just running it causes doctrine to run these queries.

为什么会发生这种情况以及如何预防呢?

Why this happening and how can I prevent it?

编辑:这是getCards()的代码.

This is the code for getCards().

/**
 * Get cards
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getCards()
{
    return $this->cards;
}

我已经找到了解决此问题的方法,尽管从长远来看它不会解决问题.我将InvoiceCards读取为数组,而不是将其作为实体进行水合处理.

EDIT 2: I've found a workaround to this problem, though it's not going to solve things in the long run. I fetch the InvoiceCards as an array, rather than having doctrine hydrate them as entities.

$query->getArrayResult();

在我目前的情况下,无论如何,这种技术还是更好的,因为我不需要完全保湿的开销.

In my current situation, this technique is better anyways, since I don't require the overhead of full hydration.

但是,该应用程序将在许多地方使用InvoiceCards,到那时原始问题仍然是个问题.我觉得我是误解了教义的懒惰加载,或者它没有按预期工作.

However, the application will be working with InvoiceCards in many places, and the original issue will be still be a problem then. I feel like either I've misunderstood Doctrine's lazy loading, or it isn't working as expected.

推荐答案

由于打印"是一个父类,其子级使用单个表继承,因此,实体急切加载.

The entities were getting eagerly loaded because Printing is a parent class whose children use single table inheritance.

如果我将$ printing更改为指向叶子实体,则可以根据需要进行延迟加载.

If I change $printing to point to leaf entity, lazy loading works as desired.

从Doctrine文档中, 7.2.2.效果影响

From the Doctrine docs, 7.2.2. Performance impact

有关单表继承的一般性能注意事项:如果多对一或一对一关联的目标实体是STI实体,出于性能方面的考虑,最好将其作为叶实体在继承层次结构中(即没有子类).否则,Doctrine 不能创建该实体的代理实例,并将始终热切地加载该实体.

There is a general performance consideration with Single Table Inheritance: If the target-entity of a many-to-one or one-to-one association is an STI entity, it is preferable for performance reasons that it be a leaf entity in the inheritance hierarchy, (ie. have no subclasses). Otherwise Doctrine CANNOT create proxy instances of this entity and will ALWAYS load the entity eagerly.

这篇关于在foreach期间阻止学说/Symfony加载关联的实体?(没有发生延迟加载)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆