如何使用QueryBuilder在Symfony上构建此查询?

时间:2018-09-10 17:34:54

标签: symfony query-builder symfony4

请问我是symfony的初学者,我有2个实体:categoryprofessionnal,ORM为多对多。 “城市”是ORM oneToMany和“专业”的实体。 在professionnel中,我有一个属性city。我想显示按professionnal分组的categories,他们在网址中的参数上放置了特殊的cityId。 我把这个查询放在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"

我也在论坛上搜索,发现可以按以下方式替换leftJoin的“ ON”,但会向我显示所有专业人员:

$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 :(得分:0)

因此,假设您已正确设置实体关系(请使用那些问题更新您的问题),我在上面看到了一个错误。

如果您查看官方的Doctrine Query Builder文档,则leftJoin方法的第三个参数是WITHON常量,而不是连接谓词。那是第四个论点。但是,即使那样,联接谓词仅在一个非常特定的用例中使用,您需要在其中进一步定义联接关系。通过查看您的示例,我怀疑那是您的情况。

话虽如此,我认为您的代码应如下所示:

$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的实体的关系?

请使用这些详细信息更新您的问题,如有必要,我将更新答案...

希望这对您有帮助...

答案 1 :(得分:0)

首先,您需要描述实体中的关系。了解有关此here

的更多信息

第二,您必须调用联接字段(作为属性读取),而不是实体。

在CategoryRepository内部:

/** @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);

因此,您将获得类别列表,其中包含professionalcity。 我建议阅读有关symfony文档的article