0

我对 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 本身不能处理这个问题,所以我希望我忽略了一些简单的事情。

4

1 回答 1

0

随着我对 Doctrine 的了解越来越多,这不起作用有一个简单的原因。没有Asset回任何组织实体的映射。换句话说,虽然 anOrganizationAssets,但 anAsset没有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,我会报告结果。

于 2013-09-13T23:12:23.263 回答