我有一个实体Shop
和一个相关实体ShopProduct
,其关系如下:
/**
* @ORM\OneToMany(targetEntity="ShopProduct", mappedBy="shopid", fetch="EXTRA_LAZY")
*/
private $products;
在twig模板中,我想访问products
的计数,因此我可以访问
{{ entity.getProducts().count }}
但是当使用symfony2探查器查看查询的数量和内容时,我发现发出了完整选择,而不是我期望的COUNT
(基于the documentation)。< / p>
为每个Shop
s发出完整选择会导致内存使用量为250Mb +,页面加载时间为30+秒,这是不可取的。
添加fetch="EXTRA_LAZY"
后,我已经清除了学说缓存。
我是否忽略了某些事情,使用了错误的方法或误解了文档?
[编辑]
doctrine/annotations v1.1
doctrine/cache v1.0
doctrine/collections v1.1
doctrine/common 2.4.0-RC1
doctrine/data-fixtures dev-master eef10f6
doctrine/dbal 2.3.3
doctrine/doctrine-bundle v1.2.0-beta1
doctrine/doctrine-fixtures-bundle dev-master 275540d
doctrine/doctrine-migrations-bundle dev-master 99c0192
doctrine/inflector v1.0
doctrine/lexer v1.0
doctrine/migrations dev-master e1f6efc
doctrine/orm 2.3.3
答案 0 :(得分:11)
刚遇到同样的问题,解决方案非常简单:
{{ value.getAlerts.count() }}
而不是
{{ value.getAlerts.count }}
Twig必须覆盖Doctrine count()
方法,这意味着&#34; Extra Lazy Load&#34;使用它的变体自己的实现,只是愚蠢地提取所有实体来计算它们。
将所有预期的SELECT *查询转换为COUNT(*)...
答案 1 :(得分:3)
你没有使用twig的计数功能,但是像这样的php内部功能。 Twig将逐个执行这些功能(首先调用getProducts导致所有产品的加载,然后计数)。
{{ entity.getProducts().count }}
自动调用getter意味着您只需输出entity.products并使用twigs内部长度过滤器来计算结果......但结果是相同的(获取所有产品)。
{{ entity.products|length }}
您真正想要的是一种设置ShopRepository提供的Shop实体的计数的方法。
public function findAllAddCount()
{
$qb = $this->createQueryBuilder('s');
$query = $qb
->set('s.productCount', $qb->expr()->count('s.products'))
->getQuery()
;
return $query->getResult();
}
...并将其添加到您的实体:
protected $productCount;
public function getProductCount()
{
return $this->productCount;
}
public function setProductCount($count)
{
$this->productCount = $count;
return $this;
}
然后在这样的树枝上输出产品数:
{{ entity.productCount }}