2012-01-16 6 views
1

国、地域、州、町の4つのエンティティがあります。Doctrine2エンティティとZendフレームワークでDQLを使用すると混乱します

<?php 

namespace Entities; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @Entity (repositoryClass="Repositories\Region") 
* @Table(name="regions") 
* @HasLifecycleCallbacks 
*/ 
class Region { 

    /** 
    * @Id @Column(type="integer") 
    * @GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** @Column(type="string", length=30,unique=TRUE) */ 
    private $regionname; 

    /** @Column(type="boolean") */ 
    private $active; 

    /** 
    * @ManyToOne(targetEntity="Country", inversedBy="regions") 
    * @JoinColumn(name="countries_id", referencedColumnName="id",nullable=FALSE) 
    */ 
    private $countries_id; 

    /** 
    * @OneToMany(targetEntity="Province", mappedBy="provinces") 
    */ 
    private $provinces; 

    public function __construct() { 
     $this->provinces = new ArrayCollection(); 
     $this->active = true; 
    } 

<?php 

namespace Entities; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @Entity (repositoryClass="Repositories\Province") 
* @Table(name="provinces") 
* @HasLifecycleCallbacks 
*/ 
class Province { 

    /** 
    * @Id @Column(type="integer") 
    * @GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** @Column(type="string", length=30,unique=TRUE) */ 
    private $provincename; 

    /** @Column(type="boolean") */ 
    private $active; 

    /** 
    * @ManyToOne(targetEntity="Region", inversedBy="provinces") 
    * @JoinColumn(name="regions_id", referencedColumnName="id",nullable=FALSE) 
    */ 
    private $regions_id; 

    /** 
    * @OneToMany(targetEntity="Town", mappedBy="towns") 
    */ 
    private $towns; 

    public function __construct() { 
     $this->towns = new ArrayCollection(); 
     $this->active = true; 
    } 

<?php 

namespace Entities; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @Entity (repositoryClass="Repositories\Town") 
* @Table(name="towns") 
* @HasLifecycleCallbacks 
*/ 
class Town { 

    /** 
    * @Id @Column(type="integer") 
    * @GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** @Column(type="string", length=30,unique=FALSE) */ 
    private $townname; 

    /** @Column(type="boolean") */ 
    private $active; 
    // so that we know when a user has added a town 
    /** @Column(type="boolean") */ 
    private $verified; 

    /** 
    * @OneToMany(targetEntity="User", mappedBy="users") 
    */ 
    private $users; 

    /** 
    * @ManyToOne(targetEntity="Province", inversedBy="towns") 
    * @JoinColumn(name="provinces_id", referencedColumnName="id",nullable=FALSE) 
    */ 
    private $provinces_id; 

    public function __construct() { 
     $this->users = new ArrayCollection(); 

     $this->active = true; 
    } 

私は私に与えられた地域のための町のリストが表示されますDQLを使用してクエリを作成したいです。今

public function findActiveTowns($provinces_id = null) 
// we can pass in a specific provinces_id if we want 
{ 

    $qb = $this->_em->createQueryBuilder(); 
    $qb->select('a.townname, a.id') 
    ->from('Entities\Town', 'a'); 

    if (!is_null($provinces_id)){ 
     $qb->where('a.provinces_id = :provinces_id AND a.active = TRUE') 
     ->setParameter('provinces_id', $provinces_id); 
    } else { 
     $qb->where('a.active = TRUE'); 
    } 

    $towns=$qb->getQuery()->getResult(); 

    // make pairs array suitable for select lists 
    $options = array(); 
    foreach ($towns as $key => $value) { 
     $options[$value['id']] = $value['townname']; 
    } 
    return $options; 
} 

、ポイントを得るために:

は、私が使用しているアクティブな町の簡単なリストを取得します。どのように私はジョインを設定し、region_idを渡してリージョン内のすべての町を返すことができるようにするためにこの作業を行うのですか?

SELECT towns.id 
FROM `towns` 
INNER JOIN `provinces` 
INNER JOIN `regions` 
WHERE regions.id =1 

ありがとう:

は、ネイティブSQLで私はこのような何かをしたいです。

答えて

3

最初にいくつか挙げてください。

  1. フィールドは識別子ではなく他のオブジェクトとの関係であるため、_idで名前を付けないでください。結合列の注釈は、実際のDB名と一緒に、オブジェクトモデルのフィールドはなくなります。
  2. すべてのフィールドをカプセル化するためのget/set/addメソッドを作成/生成するので、実際に使用できます。あなたは "外部"からプライベートフィールドを読むことはできません。

あなたの質問は、テストしていないが、このようなものはうまくいくはずです。

class Town { 
    /** 
    * @ManyToOne(targetEntity="Province", inversedBy="towns") 
    * @JoinColumn(name="provinces_id", referencedColumnName="id",nullable=FALSE) 
    */ 
    private $province; 

class Province { 
    /** 
    * @ManyToOne(targetEntity="Region", inversedBy="provinces") 
    * @JoinColumn(name="regions_id", referencedColumnName="id",nullable=FALSE) 
    */ 
    private $region; 

$qb->select('a.townname, a.id') 
    ->from('Entities\Town', 'a') 
    ->leftJoin('a.province', 'p'); 

if (!is_null($provinces_id) && !is_null($region_id)){ 
    $qb->where('a.province = :province AND a.active = TRUE') 
     ->andWhere('p.region = :region') 
     ->setParameter('province', $provinces_id) 
     ->setParameter('region', $region_id); 
} else { 
    $qb->where('a.active = TRUE'); 
} 
+0

こんにちは、あなたのポイントをありがとう。私はゲッターとセッターを持っていますが、コードをここで短くするために除外しました。 – dimbo

+0

こんにちは、私は一日中LEFTジョインをしようとしていて、このエラーに対処し続けています。 "エラー:クラスエンティティ\タウンには州という名前の関連はありません"。上記のコードを試してみましたが(WHERE条件は除く)、この同じエラーが発生します。何か案は? – dimbo

+4

プライベート$ provinces_idの名前を変更する必要があります。民間の$州へ;あなたの町のエンティティでそれはトリックを行う必要があります! –