首页 > 解决方案 > QueryBuilder 中的多对多

问题描述

对于我的 Symfony 项目,我正在创建一个表单。
在这种形式中,用户可以选择一个Animal实体,但前提是它是任何Group实体的一部分。
它们使用many-to-many关系链接。
Group实体有一个名为的属性,animals它是一个实体。CollectionAnimal

由于我使用的是many-to-many关系,因此创建了三个表animalgroupgroup_animal

现在,如果我要使用 SQL 查询,我会执行以下操作:

SELECT * FROM animal INNER JOIN group_animal ON group_animal.animal_id = animal.id

这样我就可以得到任何组中的所有动物。

问题是我正在使用 Symfony 的 FormTypes,我可以执行自定义查询的唯一方法是使用query_builder选项(https://symfony.com/doc/current/reference/forms/types/entity.html#query-建设者

我已经尝试了很多东西,但我无法将那个简单的(?)查询转换为 QueryBuilder。

我最接近的是:

$entityRepository->createQueryBuilder('animal')
    ->from('App:Group', 'group')
    ->join('group.animals', 'groupAnimal')
    ->where('groupAnimal.id = animal.id')

它有效,但现在我的“FROM”中有 2 个表,感觉不对。

谁能帮我这个?

标签: sqldoctrine-ormdoctrine

解决方案


1.使用多对多双向关系

始终对包含所需数据的表使用->from('App:Animal', 'animal')->join('animal.group', group) 。不要做相反的事情->from('App:Group', 'group')->join('group.animals', 'groupAnimal')。对于 SQL,您会得到相同的结果,但 Doctrine 无法按照您的意愿处理它。

使用内部联接仅检索分配给任何组的实体:

$entityRepository->createQueryBuilder()
    ->select('animal')
    ->from('App:Animal', 'animal')
    ->innerJoin('animal.group', group)

有关双向关系的更多信息:https ://www.doctrine-project.org/projects/doctrine-orm/en/2.8/reference/association-mapping.html#many-to-many-bidirectional

2. 单向一对多关系(推荐)

在这种情况下,您应该打破多对多关系并创建新的连接表App:AnimalGroup将这两个表连接在一起。它并不适用于所有用例,但它更具未来性,更易于阅读并准备为关系添加元数据:

use Doctrine\ORM\Query\Expr\Join;

$entityRepository->createQueryBuilder()
    ->select('animal')
    ->from('App:Animal', 'animal')
    ->innerJoin('App:AnimalGroup', 'animal_group', Join::WITH, 'animal_group.animal = animal')

在这种情况下,是否需要单向或双向关系取决于您。仅当子端不包含太多条目时,才建议使用双向关系。


推荐阅读