Doctrine orm 条令:复杂的选择,有两个多个关系
我需要在问题跟踪系统的一个表中查询多个问题,该问题跟踪系统通过一个复杂的条件限制此查询: 问题(实体)分为类别(另一实体)。人员(实体)是多个角色(第四个实体)的成员,这是一种多人关系。最后,一个角色可以访问一个或多个类别,这是第二个多人关系Doctrine orm 条令:复杂的选择,有两个多个关系,doctrine-orm,many-to-many,query-builder,Doctrine Orm,Many To Many,Query Builder,我需要在问题跟踪系统的一个表中查询多个问题,该问题跟踪系统通过一个复杂的条件限制此查询: 问题(实体)分为类别(另一实体)。人员(实体)是多个角色(第四个实体)的成员,这是一种多人关系。最后,一个角色可以访问一个或多个类别,这是第二个多人关系 <?php /** * @Entity * @Table(name="issue") */ class Issue { /** * @ManyToOne(targetEntity="Category", fetch="EAG
<?php
/**
* @Entity
* @Table(name="issue")
*/
class Issue
{
/**
* @ManyToOne(targetEntity="Category", fetch="EAGER")
* @JoinColumn(name="category", referencedColumnName="id", onDelete="RESTRICT", nullable=false)
*/
private $category;
…
}
/**
* @Entity
* @Table(name="category")
*/
class Category
{
/**
* @ManyToMany(targetEntity="Role", mappedBy="categories")
*/
private $roles;
…
}
/**
* @Entity
* @Table(name="role")
*/
class Role
{
/**
* @ManyToMany(targetEntity="Person", mappedBy="roles")
*/
private $persons;
/**
* @ManyToMany(targetEntity="Category", inversedBy="roles")
* @JoinTable(name="role_has_access_on_category",
* joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="category_id", referencedColumnName="id")}
* )
*/
private $categories;
…
}
/**
* @Entity
* @Table(name="person")
*/
class Person
{
/**
* @ManyToMany(targetEntity="Role", inversedBy="persons")
* @JoinTable(name="person_is_member_of_role",
* joinColumns={@JoinColumn(name="person_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="role_id", referencedColumnName="id")})
*/
private $roles;
…
}
$result包含具有所有关联角色的人员数据,但包含类别的空白数组,而不是实体。最后一个问题当然会从问题的一方开始,但现在我只想从另一方开始
所以现在我想知道是否我必须接受所有角色并循环它们以获取所有类别。难道没有更简单的方法吗
顺便说一下,这就是我要使用的SQL:
SELECT issue.* FROM person AS p, person_is_member_of_role AS pim, role_has_access_on_category AS rha, issue
WHERE
p.id = pim.person_id AND
pim.role_id = rha.role_id AND
rha.category_id = todo.category AND
p.id = ?;
我希望所有这些都能以某种方式说明问题,否则我将修改我的问题…您试图将所有连接条件放在
WHERE
子句中,这太复杂了
如果我正确理解了问题,查询如下所示:
SELECT
i
FROM
Issue i
JOIN
i.category c
JOIN
c.roles r
JOIN
r.persons p
WHERE
p.id = :personId
翻译成QueryBuilder
API:
$qb = $entityManager->createQueryBuilder();
$issues = $qb
->select('i')
->from('Issue', 'i')
->innerJoin('i.category', 'c')
->innerJoin('c.roles', 'r')
->innerJoin('r.persons', 'p')
->andWhere($qb->expr()->eq('p.id', ':personId'))
->setParameter('personId', $personId)
->getQuery()
->getResult();
也要考虑避免使用<代码> QueryBuilder <代码>,如果没有充分的理由使用它。毕竟,它只是一个字符串生成器。
太好了,非常感谢。尤其是expr()
部分很有趣!您说我应该避免使用QueryBuilder
,但在这种情况下可能吗?我已经可以使用常规的findByX
方法。查询生成器只需组装一个字符串(如果您对其实现感兴趣,可以检查Doctrine\ORM\QueryBuilder
的方法getQuery
)。在大多数情况下,您只需使用$em->createQuery($someDql)
。只有当您拥有一个动态组装的QueryTanks时,查询生成器才会变得非常有用!我将尝试再次检查控制器,并找到可以更改的位置。
$qb = $entityManager->createQueryBuilder();
$issues = $qb
->select('i')
->from('Issue', 'i')
->innerJoin('i.category', 'c')
->innerJoin('c.roles', 'r')
->innerJoin('r.persons', 'p')
->andWhere($qb->expr()->eq('p.id', ':personId'))
->setParameter('personId', $personId)
->getQuery()
->getResult();