在foreach期间阻止学说/Symfony加载关联的实体?(没有发生延迟加载) [英] Stop Doctrine / Symfony from loading associated entities during foreach? (lazy loading not happening)
问题描述
我看到该理论会生成其他查询来加载我不直接访问的实体.我以为延迟加载意味着这些关联实体不会被加载.您能帮我弄清楚为什么发生查询以及如何停止查询吗?
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屋!