我的后端(200)有很多产品清单。根据产品是否与订单相关联(有人购买了产品),用户将能够从列表中删除它。所以我为每个产品添加了这一行:
{% for subitemColor in subitemsColor %}
...
{% render(controller('ProjectBackendBundle:SubitemColor:checkDeletion'), {'id': subitemColor.id}) %}
...
{% endfor %}
因此生成了200行。这些行中的每一行都将调用此控制器。
public function checkDeletionAction(Request $request, $id)
{
$repository = $this->getDoctrine()->getRepository('ProjectBackendBundle:OrderSubitem');
$orders = $repository->findBy(array('subitemColor' => $id));
if (count($orders)) {
return new Response("Product in order");
} else {
return new Response('<a href="' . $this->generateUrl('project_backend_subitem_color_remove', array('id' => $id)) . '">Remove</a>');
}
}
问题 :当抛出请求时,显示结果需要花费很多时间,可能需要两分钟或更长时间..是否正常?
我知道我可以对列表进行分页并减少时间,但我希望让用户只在一个页面中显示200个结果。
答案 0 :(得分:1)
我可以推荐:
最初检索主控制器中的所有删除状态,并放入subitemsColor twig变量。然后迭代并使用简单的if-else子句。简而言之 - 将逻辑从checkDeletionAction()
移动到twig。
将存储库用作服务并将其标记为惰性lazy="true"
COUNT(*)
在存储库中创建自己的方法,并使用$queryBuilder->getQuery()->getSingleScalarResult()
以避免完全对象水合。答案 1 :(得分:0)
Controller的操作代码:
public function mainAction(){
$subitemsColor = ...;
$ids = [];
foreach ( $subitemsColor as $color ){
$ids[] = $color->getId();
}
// Populate initial map with all zeros
$countMap = array_values($ids, 0);
/**
* Returns array that look like this:
* {
* {id: id1, cnt: count1},
* {id: id2, cnt: count2},
* ....
* }
*/
$fetchedCountMap = $repository->findOrderCounts($ids);
// Replace "0" with counted value from database
foreach ( $orderCountMap as $count ){
$countMap[$count['id']] = $count['cnt'];
}
return ['subitemsColor' => $subitemsColor, 'orderCountMap': $orderCountMap];
}
存储库方法:
public function findOrderCounts(array $ids ){
return $this->getEntityManager()
->createQuery("SELECT id, COUNT(e) AS cnt FROM AcmeBundle:Entity WHERE WHEER e.id IN (:ids)")
->setParameter('ids', $ids);
->getArrayResult();
}
然后只需检查树枝中的orderCountMap
并显示链接或标签,如果值为0或更大。