QueryBuilder 和具有 ManyToMany 关系的实体

QueryBuilder and entity with ManyToMany relation

在数据库中,我有一个 table 用户 (idUser, name...) 和一个 table 角色 (IdRole, description..)。 他们两个之间有一个link table HasRole(idUser, idRole).

用Symfony命令行生成实体,没有生成HasRole实体。相反,在用户实体中,我在角色 属性 :

上有这个
* @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Role", inversedBy="utilisateur")
 * @ORM\JoinTable(name="hasrole",
 *   joinColumns={
 *     @ORM\JoinColumn(name="UTILISATEUR", referencedColumnName="ID")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="ROLE", referencedColumnName="ID")
 *   }
 * )

我想在 UserRepository 中创建一个方法,returns 所有用户都为一个 id 角色。

它应该这样开始:

$qb = $this->getEntityManager()->createQueryBuilder()
        ->select('utilisateur')
        ->from('ACCUEILBundle:User', 'utilisateur');

你能帮忙吗?

如果你使用 Doctrine 来生成你的 ManyToMany 连接 table,那么你确实不会有一个实体。

如果您需要将联接table作为一个实体(例如,因为您在那个table中存储了额外的数据),那么您应该通过以下方式创建关系:

entityA <-OneToMany-> joinEntity <-ManyToOne-> entityB

但是在您的情况下,只需获取具有所需 ID 的角色,然后从中获取用户就足够了:

$role = $entityManager->getRepository('Role')->find($id);
$users = $role->getUsers(); //(or getUtilisatuers(), if I see correctly)

我给你举了一个例子,这样你就可以把它应用到你的案例中。我已经删除了大部分实体 properties/annotation 以使您能够简单地获取图片。

在下面的示例中,存在学生 (M) 到 (N) 主题关系。要实现 M-N,您可以 Student (1) to (N) StudentSubject (N) to (1) Subject 这样关系就保存在 StudentSubject 实体中。

学生

class Student
{
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="StudentSubject", mappedBy="studentMap", cascade={"persist", "remove"})
     */
    protected $studentInverse;
}

主题

class Subject
{
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="StudentSubject", mappedBy="subjectMap", cascade={"persist", "remove"})
     */
    protected $subjectInverse;
}

学生学科

/**
 * @ORM\Entity(repositoryClass="School\FrontendBundle\Repository\StudentSubjectRepository")
 */
class StudentSubject
{
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Student", inversedBy="studentInverse")
     * @ORM\JoinColumn(name="student", referencedColumnName="id", nullable=false, onDelete="CASCADE")
     */
    protected $studentMap;

    /**
     * @ORM\ManyToOne(targetEntity="Subject", inversedBy="subjectInverse")
     * @ORM\JoinColumn(name="subject", referencedColumnName="id", nullable=false, onDelete="CASCADE")
     */
    protected $subjectMap;
}

示例查询:

此查询 select 仅给定来自学生和主题实体的字段。

class StudentSubjectRepository extends EntityRepository
{
    public function findAll()
    {
        $fields = [
            'st.id AS stId',
            'st.studentId AS stStId',
            'sb.id AS sbId',
            'sb.code AS sbCode',
        ];

        return
            $this
                ->createQueryBuilder('ss')
                ->select($fields)
                ->join('ss.studentMap', 'st')
                ->join('ss.subjectMap', 'sb')
                ->addOrderBy('st.studentId', 'ASC')
                ->addOrderBy('sb.code', 'ASC')
                ->getQuery()
                ->getResult(Query::HYDRATE_SCALAR);
    }
}