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);
}
}
在数据库中,我有一个 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);
}
}