Symfony 3.4表单重复使用EntityType查询Contact表的性能优化问题
优化方案
你遇到的性能问题根源是6个EntityType字段各自独立执行了一次全量联系人查询,按以下步骤修改即可将查询次数减少到1次:
步骤1:修改表单类支持传入预查询的联系人列表
在EventForm类中添加configureOptions方法,声明可接收预查询的联系人参数:
<?php namespace AppBundle\Form; use AppBundle\Entity\Contact; use AppBundle\Repository\ContactRepository; use Symfony\Component\OptionsResolver\OptionsResolver; class EventForm { // 新增配置方法 public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Event::class, // 替换为你原本绑定的Event实体类名 'contacts' => [], ]); $resolver->setAllowedTypes('contacts', 'array<AppBundle\Entity\Contact>'); } public function buildForm(FormBuilderInterface $builder, array $options) { // 直接取出预查询的联系人列表复用 $contactList = $options['contacts']; $builder // 其他无关的->add()调用保留 ->add('client1', EntityType::class, [ 'class' => Contact::class, // 注意你原代码里的Client::class应为Contact的笔误,按需替换 'choices' => $contactList, ]) ->add('client2', EntityType::class, [ 'class' => Contact::class, 'choices' => $contactList, ]) // client3到client6全部按上面的格式修改,删除原有的query_builder配置 ; } }
步骤2:在控制器中预查询联系人再传入表单
在渲染表单的控制器方法中,提前执行一次全量联系人查询,再作为参数传给表单:
// 你的控制器方法内 $contactRepo = $this->getDoctrine()->getRepository(Contact::class); $allContacts = $contactRepo->getAll(); // 创建表单时传入预查询的联系人列表 $form = $this->createForm(EventForm::class, $yourEventEntity, [ 'contacts' => $allContacts, ]);
额外性能优化建议
如果还需要进一步降低查询耗时,可以优化getAll()方法,仅查询表单下拉需要用到的字段(比如id、姓名),减少数据传输和实体水化时间:
// ContactRepository中的getAll方法修改 public function getAll() { return $this->createQueryBuilder('c') ->select('partial c.{id, name}') // 仅保留需要的主键和显示用字段,按需调整字段名 ->getQuery() ->getResult(); }
如果14000条选项导致前端页面加载卡顿,可以将下拉框改为AJAX自动补全组件,无需一次性加载全量联系人数据。
内容的提问来源于stack exchange,提问作者deferre_mario_po
相关产品推荐
相关产品推荐

