Как построить этот запрос на Symfony с QueryBuilder? - PullRequest
0 голосов
/ 10 сентября 2018

Пожалуйста, я новичок в Symfony, и у меня есть 2 сущности: category и professionnal со ORM многие ко многим. А «Город» - это организация с ORM oneToMany с «профессией». В professionnel у меня есть свойство city. Я хочу показать professionnal, сгруппированные по categories, у которых есть специальный cityId, помещенный в параметр в URL. Я поставил этот запрос на sql

(например, city_id = 10873)

, это дает мне результаты.

SELECT * FROM sub_category AS a LEFT JOIN professionnel ON professionnel.city_id = 10873

но я не знаю, как писать с помощью querybuilder.

Я поставил это решение, но у меня есть ошибки:

$city  = $paramFetcher->get('city');

$queryBuilder = $em->getRepository(SubCategory::class)
                    ->createQueryBuilder('a')
                    ->leftJoin('App\Entity\Professionnel','p')
                    ->where('p.city = :city')
                    ->setParameter('city', $city);


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

в журнале:

request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\Exception\SyntaxErrorException: "An exception occurred while executing 'SELECT c0_.id AS id_0, c0_.name AS name_1 FROM category c0_ LEFT JOIN professionnel p1_ WHERE p1_.city_id = ?' with params ["10873"]:  SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE p1_.city_id = '10873'' at line 1"

Я также ищу по форумам и обнаружил, что могу заменить «ON» leftJoin следующим образом, но показывает мне все профессионалы:

$city  = $paramFetcher->get('city');

$queryBuilder = $em->getRepository(SubCategory::class)
                                        ->createQueryBuilder('a')
                                        ->leftJoin('App\Entity\Professionnel','p','WITH','p.city = :city')
                                        ->setParameter('city', $city);
return $queryBuilder->getQuery()->getResult();

Для сопоставления я поставил это так:

class Category
{
/**
     * Many professionnels have Many categories.
     * @ORM\ManyToMany(targetEntity="App\Entity\Professionnel", mappedBy="Categories")
     * @ORM\JoinTable(name="professionnel_category")
     */
    private $professionnels;
}
class Professionnel extends User
{
/**
     * Many professionel have Many categories.
     * @ORM\ManyToMany(targetEntity="App\Entity\Category", inversedBy="professionnels")
     * @Groups({"Default", "professionnel", "user"})
     */
    private $categories;
}

Большое спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Во-первых, вам нужно описать отношения в сущностях.Подробнее об этом здесь

Вторично, вы должны вызывать в поле соединения (читается как свойство), а не в сущности.

внутри репозитория категорий:

/** @return ArrayCollection|Category[] */
public function getByCityId(int $cityId): ArrayCollection
{    
    $qb = $this->createQueryBuilder('category');
    $qb->leftJoin('category.professional', 'professional')
        ->leftJoin('category.city', 'city')
        ->where($qb->expr()->eq('city.id', $cityId));

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

Внутри SomeController: someAction ()

$cityId  = $paramFetcher->get('city');
$categoriesList = $this->get('doctrine.orm.entity_manager')
    ->getRepository(Category::class)
    ->getByCityId($cityId);

В результате вы получите список категорий с объединенными professional и city.Предлагаю прочитать статью на symfony docs

0 голосов
/ 10 сентября 2018

Итак, при условии, что у вас правильно установлены отношения сущностей (, пожалуйста, обновите ваш вопрос этими ), я вижу одну ошибку выше.

Если вы посмотрите официальную документацию Doctrine Query Builder, третий аргумент метода leftJoin будет либо WITH, либо ON константой, а не предикатом соединения. Этот приходит в качестве четвертого аргумента. Но даже тогда этот предикат соединения используется только в очень конкретном случае, когда вы хотите дополнительно определить свое отношение соединения. Глядя на ваш пример, я сомневаюсь, что это ваш случай.

С учетом сказанного, я думаю, ваш код должен выглядеть следующим образом:

$city  = $paramFetcher->get('city');

$queryBuilder = $em->getRepository(Category::class)
    ->createQueryBuilder('a');
    ->leftJoin('App\Entity\Professionnel','p')
    ->where('p.city_id = :city')
    ->setParameter('city', $city);

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

Теперь вопрос: действительно ли это просто city_id (простое целое число) или это отношение к некоторой сущности с именем City?

Пожалуйста, обновите ваш вопрос с этими деталями, и я буду обновлять ответ, если необходимо ...

Надеюсь, это поможет ...

...