symfony querybuilder для поиска по отношению в коллекции

#symfony #doctrine-orm #query-builder #doctrine-query

#symfony #doctrine-orm #конструктор запросов #doctrine-запрос

Вопрос:

У меня есть приложение сущности по отношению к заявителю

     /**
     * @ORMManyToOne(targetEntity=Applicant::class, inversedBy="applications")
     * @ORMJoinColumn(nullable=false)
     */
    private $applicant;
  

теперь я пытаюсь создать QueryBuilder для приложения поиска по имени заявителя в ApplicantRepository, у меня есть

     public function searchByName($searchString)
    {
        return $this->createQueryBuilder('a')
            ->andWhere('a.name LIKE :phrase')->setParameter('phrase', '%'.$searchString.'%')
            ->getQuery()
            ->getResult();
    }
  

в контроллере у меня есть

 $applicants = $applicantRepository->searchByName($searchString);
  

Теперь я хочу, чтобы поисковое приложение с именем заявителя находилось в этой коллекции кандидатов. Могу ли я использовать QueryBuilder для этого?

Я пытаюсь что-то вроде этого

 public function getApprovedSearchByApplicants($applicants)
    {
        return $this->createQueryBuilder('a')
            ->andWhere('a.applicant IN (:applicants)')
            ->setParameter('applicants', $applicants)
            ->getQuery()
            ->getResult();
    }
  

Комментарии:

1. Вы уверены, что Application::$applicant === Applicant::$name ?

2. Попробуйте добавить referencedColumnName="name" в @JoinColumn() аннотацию

3. Я пытаюсь выполнить поиск во всех приложениях, в которых есть имя заявителя с текстом поиска

4. Кроме того, если вы ищете приложение — вам нужно использовать ApplicationRepository, а не ApplicantRepository и просто искать, как $appRepo->findBy(['applicant' => $applicantEntity->getId()]) , если я вас правильно понимаю.

5. Да, вы правы, но мой $ заявитель, возможно, коллекция $ заявителя

Ответ №1:

итак, глядя на вашу конфигурацию, ваш Application::$applicant === Applicant::$name , просто потому Application::$applicant Applicant::$id , что свойство по умолчанию имеет значение. Вы можете проверить документацию.

Итак, таким образом, вам нужно сделать что-то вроде этого:

 /**
 * @ORMManyToOne(targetEntity=Applicant::class, inversedBy="applications")
 * @ORMJoinColumn(name="applicant_name", referencedColumnName="name", nullable=false)
 */
private $applicant;
  

Это должно сработать.

ОБНОВЛЕНИЕ после обновления вопроса и обсуждений:

Итак, проблема заключалась в тестовых данных в базе данных. Плохой вопрос.

Комментарии:

1. Да, я продолжил в ответах, я обнаружил, что вы использовали неправильный репозиторий для получения приложений.

Ответ №2:

Я не тестировал его, но что-то вроде следующего кода должно сработать. Это почти такое же решение, как предложил goulashsoup, но без ввода необработанного DQL.

 /**
 * @param array|Applicant[] $applicants
 *
 * @return array|Application[]
 */
public function findByApplicants(array $applicants): array
{
    $qb = $this->createQueryBuilder('a')

    return $qb->innerJoin('a.applicant', 'at')
        ->where(
            $qb->expr()->in('at.id', ':applicants')
        )
        ->setParameter('applicants', $applicants)
        ->getQuery()
        ->getResult();
}
  

Я не думаю, что вам нужно называть функцию с именем «ApprovedSearch», поскольку методу известен только список кандидатов, для которых вы хотите получить список заявок.

Ответ №3:

Поиск по строке поиска:

 $entityManager
    ->createQuery('
        SELECT ct
        FROM AppEntityApplication ct
            JOIN ct.applicant nt
        WHERE nt.name LIKE :phrase
    ')
    ->setParameters(['phrase' => "%$searchString%"])
    ->getResult();
  

Поиск по кандидатам:

 $entityManager
    ->createQuery('
        SELECT ct
        FROM AppEntityApplication ct
            JOIN ct.applicant nt
        WHERE nt IN (:nts)
    ')
    ->setParameters(['nts' => $applicants])
    ->getResult();