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

问题描述 投票:0回答:2

请问我是symfony的初学者,我有两个实体:categoryprofessionnal,ORM很多。而'City'是ORM oneToMany与'professionnal'的实体。在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;
}

非常感谢你的帮助。

symfony query-builder symfony4
2个回答
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的实体的关系?

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

希望这可以帮助...


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();
}

Inside SomeController里面:someAction()

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

结果你将获得类别列表,加入professionalcity。我建议在symfony docs上阅读这个article

© www.soinside.com 2019 - 2024. All rights reserved.