[英]Doctrine2 / Symfony2: One-Way Many-to-Many Query with Left Join
我对Doctrine比较陌生,但是对SQL相当精通。 我似乎无法在Symfony 2.3应用程序中有效地将以下MySQL查询转换为Doctrine:
select
asset.id as asset_id,
orgAsset.organization_id,
districtAsset.district_id,
deptAsset.department_id,
subjectAsset.subject_id,
schoolAsset.school_id,
teacherAsset.teacher_id,
sectionAsset.section_id,
syllabusAsset.syllabus_id
from asset
left join organizations_assets orgAsset on asset.id = orgAsset.asset_id
left join districts_assets districtAsset on asset.id = districtAsset.asset_id
left join departments_assets deptAsset on asset.id = deptAsset.asset_id
left join subjects_assets subjectAsset on asset.id = subjectAsset.asset_id
left join schools_assets schoolAsset on asset.id = schoolAsset.asset_id
left join teachers_assets teacherAsset on asset.id = teacherAsset.asset_id
left join sections_assets sectionAsset on asset.id = sectionAsset.asset_id
left join syllabus_assets syllabusAsset on asset.id = syllabusAsset.asset_id
where asset.id = ?;
所有*_assets
表都是单向多对多表,其中*
对象连接到Asset
对象。
我的第一个目标是使用Doctrine来使这种查询正常工作。 我的最终目标是让Doctrine仅返回与资产关联的对象。 这是我的单向多对多对象映射的示例。 Asset
对象中没有相互映射:
class Organization
{
...
/**
* @ORM\ManyToMany(targetEntity="Asset")
* @ORM\JoinTable(name="organizations_assets",
* joinColumns={@ORM\JoinColumn(name="organization_id", referencedColumnName="id", nullable=true)},
* inverseJoinColumns={@ORM\JoinColumn(name="asset_id", referencedColumnName="id")}
* )
*
* @var ArrayCollection|Asset[]
*/
protected $assets;
...
}
扩展Asset
的对象太复杂,无法实际重构为单表继承。
单向映射是问题吗? 我是否需要创建一个本地查询来处理此问题? 我很难相信Doctrine本身无法解决这个问题,所以我希望我能忽略一些简单的事情。
随着我对Doctrine的了解越来越多,有一个简单的原因表明它不起作用。 Asset
中没有任何映射回任何组织实体的映射。 换句话说,虽然Organization
拥有Assets
,但是Asset
没有Organization
, School
, District
等。
如我所见,以下是针对此问题的几种解决方案:
1)创建与Asset
每个组织对象的关联。 这不是性感的,并且可能效率低下。
2)创建一个AssetContainer
并利用每个组织对象的继承(可能是单表)。 这很性感,但是会涉及一些重构。 它看起来像这样:
/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"organization" = "OrganizationAsset", "district" = "DistrictAsset"})
*/
class AssetContainer
{
protected $id;
protected $asset; // join to Asset
}
class OrganizationAsset extends AssetContainer
{
protected $organization; // join to Organization
}
class DistrictAsset extends AssetContainer
{
protected $district; // join to District
}
class Asset
{
...
protected $assetContainers; // join to AssetContainer
...
}
3)运行一个简单的SQL查询(请参阅OP)并根据需要进行合并。 不如#2性感,但无需重构即可快速修复。
我很确定我要使用#2或#3。 如果我选择#2,我将报告结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.