Symfony 5.4查询参数错误及实习生筛选问题求助
Symfony 5.4 查询参数问题排查与解决
一、最初"Too few parameters"错误的原因
最初的Repository代码中,错误地在单个参数前使用了IN()语法:
->andWhere('st.finStage >= IN(:dateDebut)') ->andWhere('st.finStage <= IN(:dateFin)') ->andWhere('st.isDeleted = IN(:delete)')
IN()用于匹配集合类型的参数(比如数组),单个参数直接使用=, >=, <=即可,不需要包裹IN()。这种错误语法会导致Doctrine的QueryBuilder无法正确解析参数绑定,进而出现参数数量不匹配的报错。
二、动态参数无法生效的问题修复
调整后的代码存在以下几个关键问题,导致动态参数不生效:
1. 查询方法未返回结果
调整后的findByDate方法最后执行了$query->getQuery()->getResult(),但没有用return返回结果,调用该方法时无法获取筛选后的数据。
2. 日期筛选逻辑错误
需求是筛选实习结束时间在dateDebut到dateFin区间内的实习生,但代码中两个条件都写了<=:
$query->andWhere('st.finStage <= :dateDebut') // 应为 >= $query->andWhere('st.finStage <= :dateFin')
逻辑完全颠倒,导致筛选结果不符合预期。
3. 不必要的日期格式化
如果实体中finStage字段是DateTime类型,直接传递DateTime对象给setParameter即可,Doctrine会自动处理数据库的日期类型转换,不需要手动转成Y-m-d字符串。
4. 控制器未接收查询结果
调用findByDate后没有保存返回值,且dd($bordereauRepository)无法查看筛选结果,应该直接打印查询返回的数据。
修正后的Repository代码
public function findByDate(BordereauEditModel $bordereau, bool $isDeleted = false) { $query = $this->createQueryBuilder('bo') ->select('bo', 'bord_stag', 'st') ->leftJoin('bo.bordereauStagiaire', 'bord_stag') ->leftJoin('bord_stag.stagiaire', 'st') ->andWhere('st.isDeleted = :delete') ->setParameter('delete', $isDeleted); if ($bordereau->dateDebut) { $query->andWhere('st.finStage >= :dateDebut') ->setParameter('dateDebut', $bordereau->dateDebut); } if ($bordereau->dateFin) { $query->andWhere('st.finStage <= :dateFin') ->setParameter('dateFin', $bordereau->dateFin); } // 必须返回查询结果 return $query->getQuery()->getResult(); }
修正后的控制器代码
#[Route('/{id}/edit', name: 'app_bordereau_edit', methods: ['GET', 'POST'])] public function edit(Request $request, Bordereau $bordereau, BordereauRepository $bordereauRepository): Response { $bordereauEdit = new BordereauEditModel(); $formBordereau = $this->createForm(BordereauEditType::class, $bordereauEdit); $formBordereau->handleRequest($request); if ($formBordereau->isSubmitted() && $formBordereau->isValid()) { // 接收筛选后的结果 $filteredData = $bordereauRepository->findByDate($bordereauEdit); // 这里可根据需求处理筛选结果,比如关联到当前薪资单等 // $bordereau->setXXX($filteredData); // $bordereauRepository->save($bordereau, true); dd($filteredData); // 查看筛选结果是否符合预期 return $this->redirectToRoute('app_bordereau_index', [], Response::HTTP_SEE_OTHER); } return $this->renderForm('bordereau/edit.html.twig', [ 'bordereau' => $bordereau, 'form' => $formBordereau, ]); }
内容的提问来源于stack exchange,提问作者Ralda00
相关产品推荐
相关产品推荐

