Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Doctrine orm 条令:复杂的选择,有两个多个关系_Doctrine Orm_Many To Many_Query Builder - Fatal编程技术网

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