我有以下相关数据库表的设置:
Organization
+--------+---------+
| id | integer |
+--------+---------+
| name | string |
+--------+---------+
Division
+---------------+---------+
| id | integer |
+--------+----------------+
|organization_id| integer |
+---------------+---------+
| name | string |
+---------------+---------+
Subdivision
+---------------+---------+
| id | integer |
+--------+----------------+
| division_id | integer |
+---------------+---------+
| name | string |
+---------------+---------+
我正在使用带有Doctrine2 ORM的Symfony2和FOSRestBundle。
现在我对协会映射感到困惑。
当我需要组织时,我希望得到以下内容
{
id: 1,
name: "organization1",
divisions: [
{
id: 1,
organization_id: 1,
name: "division1"
subdivisions: [
{
id: 1,
division_id: 1,
name: "subdivision1"
}
]
}
]
}
我想出了这个,并使用了One-To-Many bidirectional association mapping of Doctrine。
让我头疼的是这种关系的相反方向。 如果我需要一个特定的细分,我想得到以下内容:
{
id: 1,
division_id: 1,
name: "subdivision1",
division: {
id: 1,
organization_id: 1,
name: "division1"
organization: {
id: 1,
name: "organization"
}
}
]
}
但我明白了:
{
id: 1,
division_id: 1,
name: "subdivision1",
division: {
id: 1,
organization_id: 1,
name: "division1",
organization: {
id: 1,
name: "organization1",
divisions: [/* ..list of all the other divisions.. */]
},
subdivisions: [/* ..list of all the other subdivisions.. */]
}
}
如何使用Doctrine从返回的数据中删除细分和分区?
因为我只需要细分,它所属的部门和部门所属的组织。列出所有树需要大量数据和时间,而我并不需要全部。
修改
我正在使用以下内容来检索记录(每件事都按预期工作):
$organization = $this
->getDoctrine()
->getRepository('MyTestBundle:Organization')
->find($id);
$organization = $this
->getDoctrine()
->getRepository('MyTestBundle:Organization')
->findAll();
反方向:
$subdivision = $this
->getDoctrine()
->getRepository('MyTestBundle:Subdivision')
->find($id);
这将生成以下SQL:
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.id = ? ["11"] []
SELECT t0.id AS id1, t0.organization_id AS organization_id2, t0.name AS name3, t0.organization_id AS organization_id4 FROM Division t0 WHERE t0.id = ? [16] []
SELECT t0.id AS id1, t0.name AS name2 FROM Organization t0 WHERE t0.id = ? [15] []
SELECT t0.id AS id1, t0.organization_id AS organization_id2, t0.name AS name3, t0.organization_id AS organization_id4 FROM Division t0 WHERE t0.organization_id = ? [15] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [15] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [18] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [19] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [45] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [49] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [51] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [56] []
SELECT t0.id AS id1, t0.division_id AS division_id2, t0.name AS name3, t0.division_id AS division_id4 FROM Subdivision t0 WHERE t0.division_id = ? [16] []
答案 0 :(得分:0)
将$subdivision ... ->find($id)
替换为
$subdivision = $this
->getDoctrine()
->getRepository('MyTestBundle:Subdivision')
->createQueryBuilder('s')
->leftJoin('s.division', 'd')
->leftJoin('d.organization', 'o')
->where('s.id = :id')
->setParameter('id', $id)
->getQuery()
->getSingleResult();
这应该已经降低了Doctrine请求的数量。当然divisions
的{{1}}属性仍然存在,但内容不会自动加载第一个查询。如果您通过organization
访问该属性,则将从数据库加载内容。它是Doctrine的一个特性,可以在不让开发人员考虑的情况下加载必要的数据。当然,它不是最高效的方式,你必须根据自己的需要采用它。请查看lazy loading及相关主题。