QueryBuilder和具有ManyToMany关系的实体

时间:2016-08-08 13:21:02

标签: symfony doctrine query-builder

在数据库中,我有一个表User(idUser,name ...)和一个表Role(IdRole,description ..)。 在他们两个之间有一个链接表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中创建一个方法,该方法返回一个id Role的所有用户。

应该这样开始:

$qb = $this->getEntityManager()->createQueryBuilder()
        ->select('utilisateur')
        ->from('ACCUEILBundle:User', 'utilisateur');
你帮忙吗?

2 个答案:

答案 0 :(得分:1)

如果您使用Doctrine生成ManyToMany连接表,那么您确实没有实体。

如果您需要将连接表作为实体(例如,因为您在该表中存储了其他数据),那么您应该按以下方式创建关系:

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

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

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

答案 1 :(得分:0)

我给你举个例子,以便你可以将它付诸实践。我删除了大部分实体属性/注释,以便您轻松获取图片。

在下面的示例中,存在学生(M)到(N)主题关系。要实现M-N,您可以将Student(1)到(N)StudentSubject(N)改为(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;
}

<强> StudentSubject

/**
 * @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;
}

示例查询:

此查询仅选择Student和Subject实体中的给定字段。

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