2011-12-19 13 views
2

我正在試圖做5個對象與Doctrine2(PHP)的關聯。 我正在使用PostgreSQL。2表與Doctrine2之間的雙關聯PHP

下面是數據庫模式: Database schema

一個公司可以有多個集線器,每個集線器有一個港灣。 一家公司可能有多條線路,每條線路都有一個線路列表。 一個線路列表有2個港口。 例如,線列表是「洛杉磯 - 西雅圖」,多個公司可能擁有它,這要歸功於線表。

我試圖查詢一家公司的所有Hub,Harbor,Linelist和Line。 我有SQL查詢:

SELECT * 
FROM hub h 
JOIN harbor a 
ON a.id = h.harbor_id 
JOIN linelist l 
ON (l.harborstart_id = a.id OR l.harborend_id = a.id) 
JOIN line m 
ON m.linelist_id = l.id 
WHERE h.company_id = 41 
AND m.company_id = 41" 

我試圖做使用DQL相同。 我想這一點,但它不工作:

$query = $this->getEntityManager() 
->createQuery('SELECT h, a, l, m 
       FROM AmGameBundle:Hub h 
       JOIN h.harbor a 
       JOIN a.linelist l 
       JOIN l.line m 
       WHERE h.company = :company_id 
       AND m.company = :company_id') 
->setParameter('company_id', $company_id); 

結果,我只有LineList和線對象匹配harborstart_id,但我想要的匹配要麼harborstart_id或harborend_id。

你認爲這在DQL中是可行的嗎? 將Harbor和Linelist之間的關係更改爲多對多可能更好?

回答

0

我認爲這是在你的實體定義2個關係從港口linelist的問題。我想你有類似

<?php 
/** 
* @Entity 
* @Table(name="LineList") 
*/ 
class LineList { 
    /** 
    * @var object $startHarbor 
    * @ManyToOne(targetEntity="Harbor", inversedBy="startHarbors") 
    * @JoinColumn(name="harborstart_id", referencedColumnName="id", nullable=FALSE) 
    */ 
    protected $startHarbor; 
} 

/** 
* @Entity 
* @Table(name="Harbor") 
*/ 
class Harbor { 
    /** 
    * @var object $startHarbors 
    * @OneToMany(targetEntity="LineList", mappedBy="startHarbor") 
    */ 
    protected $startHarbors; 
} 

這將讓你加入港口到LineLists通過harborstart_id(你命名變量linelist,但我認爲現在是更好的改變標識符一樣,還會有2指相同的外部表),那麼如果你想harborend_id

<?php 
/** 
* @Entity 
* @Table(name="LineList") 
*/ 
class LineList { 
    /** 
    * @var object $startHarbor 
    * @ManyToOne(targetEntity="Harbor", inversedBy="startHarbors") 
    * @JoinColumn(name="harborstart_id", referencedColumnName="id", nullable=FALSE) 
    */ 
    protected $startHarbor; 

    /** 
    * @var object $endHarbor 
    * @ManyToOne(targetEntity="Harbor", inversedBy="endHarbors") 
    * @JoinColumn(name="harborend_id", referencedColumnName="id", nullable=FALSE) 
    */ 
    protected $endHarbor; 
} 

/** 
* @Entity 
* @Table(name="Harbor") 
*/ 
class Harbor { 
    /** 
    * @var object $startHarbors 
    * @OneToMany(targetEntity="LineList", mappedBy="startHarbor") 
    */ 
    protected $startHarbors; 

    /** 
    * @var object $endHarbors 
    * @OneToMany(targetEntity="LineList", mappedBy="endHarbor") 
    */ 
    protected $endHarbors; 
} 

現在你可以在DQL更改爲:

$query = $this->getEntityManager() 
->createQuery('SELECT h, a, sh, eh, m 
       FROM AmGameBundle:Hub h 
       JOIN h.harbor a 
       JOIN a.startHarbors sh 
       JOIN a.endHarbors eh 
       JOIN l.line m 
       WHERE h.company = :company_id 
       AND m.company = :company_id') 
->setParameter('company_id', $company_id); 

這應該讓你走向正確的方向。如果它變得很麻煩,那麼你推測的多對多方法應該是一個有據可查的解決方案。

+0

你可能只是想直接去多對多,看看這個線程:http://stackoverflow.com/questions/8919910/is-it-possible-to-reference-a-column-other-比-ID-FOR-A-joincolumn/8959222#8959222 – quickshiftin 2012-01-24 18:37:18