在Symfony中具有关系的QueryBuilder

ckx4rj1h  于 2022-11-16  发布在  其他
关注(0)|答案(2)|浏览(144)

我在Symfony中编写了一个搜索栏,它与一个名为“Structure”的实体的查询生成器一起工作,该实体与一个实体“Partenaire”(一对多)相关,它工作得很好,但问题是它显示了所有的结构,而我只需要显示与Partenaire相关的结构。如果有人能帮助我解决这个问题,谢谢。
PartenaireController.php:

#[Route('/{id}', name: 'app_partenaire_show', methods: ['GET', 'POST'])]
public function show(Partenaire $partenaire, EntityManagerInterface $entityManager, PartenaireRepository $partenaireRepository,Request $request, PartenairePermissionRepository $partenairePermissionRepository, StructureRepository $structureRepository): Response
{
    $getEmail = $this->getUser()->getEmail();
    $partenaireId = $entityManager->getRepository(Partenaire::class)->findOneBy([
        'id' => $request->get('id')
    ]);

    $search2 = $structureRepository->findOneBySomeField2(
        $request->query->get('q')
    );
    
    return $this->render('partenaire/show.html.twig', [
        'partenaire' => $partenaire,
        'permission'=>$partenairePermissionRepository->findBy(
            ['partenaire' => $partenaireId],
        ),
      'structures'=>$search2, // show all the structures

      /*  'structures'=>$structureRepository->findBy( // show the structure linked to the partenaire but doesn't work with the search
            ['partenaire' => $partenaireId],
            [],
        ),*/
        'email'=>$getEmail,
    ]);
}

结构库. php:

public function findOneBySomeField2(string $search2 = null): array
{
    $queryBuilder =  $this->createQueryBuilder('q')
        ->orderBy('q.id' , 'ASC');

    if ($search2) {
        $queryBuilder->andWhere('q.Adresse LIKE :search')
            ->setParameter('search', '%'.$search2.'%');
    }

    return $queryBuilder->getQuery()
        ->getResult()
        ;
}
72qzrwbm

72qzrwbm1#

因为它是一个一对多关系,所以您应该连接正确的表并在结构查询中添加where语句,如下所示:

public function findByPartenaireWithFilter(Partenaire $partenaire, string $search2 = null): array
{
    $queryBuilder =  $this->createQueryBuilder('q')
        ->leftJoin('q.partenaire','p')
        ->where('p.partenaire.id = :partenaireId')
        ->setParameter('partenaireId', $partenaire->getId())
        ->orderBy('q.id' , 'ASC');

    if (null !== $search2) {
        $queryBuilder->andWhere('q.Adresse LIKE :search')
            ->setParameter('search', '%'.$search2.'%');
    }

    return $queryBuilder
        ->getQuery()
        ->getResult();
}
ws51t4hk

ws51t4hk2#

您需要通过添加一个条件来将结果限制为所需的Partenaire。您可以通过向repository函数传递另一个参数来实现这一点。
我已经删除了控制器中的注解代码和Partenaire实体的加载,因为它 * 应该 * 已经被加载,这要归功于param converters的魔力。

#[Route('/{id}', name: 'app_partenaire_show', methods: ['GET', 'POST'])]
public function show(Partenaire $partenaire, EntityManagerInterface $entityManager, Request $request, PartenairePermissionRepository $partenairePermissionRepository, StructureRepository $structureRepository): Response
{
    $getEmail = $this->getUser()->getEmail();
    // The Partenaire should already be loaded

    $result = $structureRepository->findByPartenaireWithFilter(
         $partenaire,
         $request->query->get('q')
    );
    
    return $this->render('partenaire/show.html.twig', [
        'partenaire' => $partenaire,
        'permission' => $partenairePermissionRepository->findBy(
            ['partenaire' => $partenaireId],
        ),
        'structures' => $search2, // show all the structures
        'email' => $getEmail,
    ]);
}

至于存储库,非常简单:传递已加载的partenaire并添加where子句。

public function findByPartenaireWithFilter(Partenaire $partenaire, string $search2 = null): array
{
    $queryBuilder =  $this->createQueryBuilder('q')
        ->where('q.partenaire = :partenaire')
        ->setParameter('partenaire', $partenaire)
        ->orderBy('q.id' , 'ASC');

    if (null !== $search2) {
        $queryBuilder->andWhere('q.Adresse LIKE :search')
            ->setParameter('search', '%'.$search2.'%');
    }

    return $queryBuilder
        ->getQuery()
        ->getResult();
}

至于控制器中的permissions键,我想你正在尝试做什么,我建议你研究一下security voters

相关问题