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組織エンティティに戻るマッピングはありません。言い換えると、 には がありますが、 にOrganizationは、、などはAssetsありAssetません。OrganizationSchoolDistrict

私が見ているように、この問題に対するいくつかの解決策があります。

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 に答える