我正在建立一个带有>的网上商店40k产品。这些产品存储在MySQL表中(表格生成Symfony 2控制台和Doctrine 2)。
我有一个采购订单系统并创建了一个表单。
[table purchase_orders]
[table purchase_order_rows](fk purchase_order_id和fk product_id)
[表产品](产品(许多属性的RAM模块)(fk brand_id)
[table product_brands]
PurchaseOrderType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('customer', 'entity', array(
'class' => 'MyShop\Bundle\CustomerBundle\Entity\Customer',
'multiple' => false
))
->add('purchaseOrderStatus', 'entity', array(
'class' => 'AppBundle\Entity\PurchaseOrderStatus',
'multiple' => false
))
->add('date')
->add('reference')
->add('comments')
->add('purchaseOrderRows', 'collection', [
'type' => new PurchaseOrderRowType(),
'allow_add' => true,
'by_reference' => false,
])
;
}
PurchaseOrderRowType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('purchaseOrder', 'entity', array(
'class' => 'AppBundle\Bundle\OrderBundle\Entity\PurchaseOrder',
'multiple' => false
))
->add('ram', 'entity', array(
'class' => 'MyShop\Bundle\ProductBundle\Entity\Ram',
'multiple' => false,
))
->add('purchaseOrderRowStatus', 'entity', array(
'class' => 'AppBundle\Entity\PurchaseOrderRowStatus',
'multiple' => false
))
->add('description')
->add('count')
->add('startDate')
->add('endDate')
->add('amount')
->add('taxAmount')
->add('discountAmount')
;
}
当我使用Doctrine生成表单时,它会从products表中加载所有行,这会导致非常慢/不可加载的网页。 如何设法不预先加载所有这些产品?每个产品都有一个唯一的条形码,用户和数据库都知道。用户只需输入条形码,而不是从下拉列表中选择产品。
我一直在尝试将关键query_builder添加到 - > add('ram','entity'但这不会导致解决方案,我卡住了......
同时添加新的采购订单的成本超过30秒!我怀疑这个问题也会引起这种情况。
非常感谢任何帮助。
答案 0 :(得分:1)
我能看到的一个解决方案是创建一个DataTransformer,它将条形码转换为产品实体和v.v. Here是几乎准备好的示例,您可以稍微更改并使用它,可选地,您可以向该文本字段添加一些jquery插件(例如自动完成)以获得更多可用性。
答案 1 :(得分:1)
我们遇到了类似的问题,这是我们提出的解决方案:
您应该考虑创建最终类 ProductForChoice,将EntityManager作为依赖项和单个调用方法:
/**
* Class ProductForChoice
*/
final class ProductForChoice
{
/** @var EntityManager */
protected $entityManager;
function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function invoke()
{
$dql = "
SELECT product.id, product.barCode as bar_code
FROM Entity/Product as product
";
$query = $this->entityManager->createQuery($dql);
$results = $query->useResultCache(true, 300)->getArrayResult();
$ret = [];
foreach ($results as $result) {
$ret[$result['id']] = $result['bar_code'];
}
return $ret;
}
}
然后在确定将此类注册为服务之后,您可以以这种方式在抽象类型中使用它:
->add('product', 'filter_choice', [
'required' => false,
'choices' => $this->ProductForChoiceAsService->invoke(),
'label' => 'Products',
]);
请注意,在此示例中,存在 filter_choice ,而不是实体。
作为旁注,如果你想保留你的抽象类型,dependecy-clean你可能想要传递 ProductForChoiceAsService 在表单选项中,而不是使用__constructor,您的电话。
为了帮助用户完成任务,可以考虑采用 Choosen,这是一个非常讨厌的工具,可以将多选项转换为类似搜索的输入框。
希望它有所帮助, 问候。