2017-07-05 3 views
1

への間接的な一つは、私が唯一this questionを思い付きました。私が知りたいのは、その質問とは正反対であるので、私はそれを構築しています。同じエンティティを考える:ドクトリン2 - 間接的な団体を探して多くの後、多くの関連

class Continent { 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", name="id") 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\Country", mappedBy="continent") 
    */ 
    private $countries; 
} 


class Country { 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", name="id") 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Continent", inversedBy="countries") 
    * @ORM\JoinColumn(name="continent_id", referencedColumnName="id") 
    */ 
    private $continent; 

    /** 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\City", mappedBy="country") 
    */ 
    private $cities; 
} 

class City { 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", name="id") 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", inversedBy="cities") 
    * @ORM\JoinColumn(name="country_id", referencedColumnName="id") 
    */ 
    private $country; 
} 

おそらく、国のコレクションと同じようにフィールドに、カスタムクエリを毎回構築することなく、大陸内のすべての都市のコレクションを持ってする方法はありますアノテーションや多分動的マッピングを介して?

私が考えることができる唯一の方法は、リポジトリのfind...メソッドをオーバーライドすることです。フィールドの追加をどのように正確に達成できたかわかりません。そして、国をループして新しい都市に都市を追加します。コレクション、またはカスタムクエリを完全に使用することができます。あなたのマッピングについてのコメント

+0

動作したらこの設定で何をするつもりですか? – Doug

+1

あなたが大陸のすべての都市を持っていたい場合、各国のすべての都市を大陸で作成する機能を作成します – Edwin

+0

これは私が必要とする設定ではありませんが、使用するのに十分な直感的な例でした。私の実際のシナリオには、実際には地理的な領域が含まれています。このプロジェクトには、Symfonyダッシュボードと、RESTful API経由でデータにアクセスするモバイルアプリが含まれています。アプリのデザイン時に「大陸」の計画は立てていませんでした。それが追加されたとき、互換性については何の注意も払われず、新しい "City"を登録するときにアプリは "Continent"を送信せず、 "Continent"もnullにすることはできません。すべての「都市」には「国」があり、すべての「国」は「大陸」にあるので、それは道のりです – Mismatch

答えて

1

まず。あなたの代わりにcontinentt_id

/** 
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Continent", inversedBy="countries") 
* @ORM\JoinColumn(name="continent_id", referencedColumnName="id") 
*/ 
private $continent; 

continent_idという名前の列をしたい

inversedBy="countries"ないinversedBy="country"、おそらく、ここにはinversedBy="cities"ないinversedBy="city"する必要があります:あなたのマッピングは、ここで間違っている

/** 
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", inversedBy="cities") 
* @ORM\JoinColumn(name="country_id", referencedColumnName="id") 
*/ 
private $country; 

は、検証を使用することを検討してくださいあなたのエンティティモデル、教義ORMを持つ船がこれらの事が正しい取得するためにあなたを助ける検証ツールのため。


このような結果セットは、ある大陸の国々に内在することで得ることができます。あなたのCityRepositoryインサイド

use Doctrine\ORM\Query\Expr\Join; 

//... 

public function findCitiesByContinent($params){ 
    $queryBuilder = $this->createQueryBuilder('c') 
     ->innerJoin('c.country', 'cc', Join::WITH, 'cc.continent = :continent') 
     ->setParameter('continent', $params['continent']); 

    $query = $queryBuilder->getQuery(); 
    return $query->getResult(); 
} 

クエリを再利用し、ちょうどあなたの$params配列には、異なる大陸のために都市をするたびに大陸に異なる値を渡すことができます。

このコード

がテストされていませんが、私はそれが動作するはずだと思います。これをテストする際に問題に遭遇した場合は、コメントを残してください。


@Edwinのようなメソッドを追加することもできますが、すべてのエンティティを読み込むように気を付ける必要があります。あなたは、テーブル内の行の膨大な量(都市や国の多くを)持っている場合、これは、パフォーマンスのために殺害されます。そのため、リポジトリ内のクエリがより良いものになります。


また、条件とコレクションのフィルタリングを使用してエンティティ内で行うこともできます。コレクションは、データベースからロードされていない場合は

:あなたは、フィルタを使用する利点も良くドキュメントで説明されて8.8. Filtering Collections

ドキュメントの章で、ここでこれを行う方法で読むことができますフィルタリングAPIはSQLレベルで動作し、大規模なコレクションに最適化されたアクセスを行うことができます。

+0

私はこれらの間違いを修正しました - 私が以前コメントしたように、これらは私の実際の実体ではありません。私は単純化のために例として借りただけです。 今のところ、@Edwinが示唆しているように、私は終わりました。既存のゲッターを保持し、内部をループしてすべてを取得しますが、パフォーマンスが心配です。プロジェクトがまだ完全には開発されていないので、私は他の2つのオプションも試してみることができましたが、私は他のものと同じフォーマットを保つことができるものを考えていました。どのようなアイデアをゲッターを保つが、熱心に読み込まないでください? – Mismatch

+0

* "私は同じフォーマットを維持できると思っていました" *と書いていますが、都市のリポジトリに追加のクエリ/メソッドを追加することでエンティティが変更されることはありません。問題が何であるか説明できますか? – Wilt

+0

追加のクエリまたはメソッドがエンティティ自体を変更するのではなく、ルート "大陸"エンティティを追加した元の変更にはゲッターを使用するコントローラコードも含まれていたので、おそらく破損を避ける方法を探していましたパフォーマンスを念頭に置きながら私は厳密に余分なクエリを読み込んだり、実行したりするのを避けるために、CriteriaとCollection Filteringを正確に適用する方法がわかりませんでした... – Mismatch

関連する問題