2017-07-11 60 views
0

,這與實體BC通過可選多對一的關係連接主義XOR兩個關係 - 這將是確保只有那些關係之一在使用的最佳方法時間(XOR)?給出一個實體<code>A</code>實體

我想要實現的是相當不錯在下圖所示(基數顯示方式有所不同):

enter image description here

當然,我可以確保引用一個庫下有效代碼或其他地方,但也許有更合適的方式來使用Doctrine映射功能來做到這一點?

一個

/** 
* @ORM\Table(name="A") 
* @ORM\Entity(repositoryClass="Test\AppBundle\Repository\ARepository") 
*/ 
class A 
{ 
    /** 
    * @var 
    * @ORM\ManyToOne(targetEntity="B", inversedBy="as", cascade={"all"}) 
    */ 
    private $b = null; 

    /** 
    * @var null 
    * @ORM\ManyToOne(targetEntity="C", inversedBy="as", cascade={"all"})) 
    */ 
    private $c = null; 
} 

/** 
* @ORM\Table(name="B") 
* @ORM\Entity(repositoryClass="Test\AppBundle\Repository\BRepository") 
*/ 
class B 
{ 
    /** 
    * @var 
    * @ORM\OneToMany(targetEntity="A", mappedBy="b", cascade={"all"}) 
    */ 
    private $as = null; 
} 

Ç

/** 
* @ORM\Table(name="C") 
* @ORM\Entity(repositoryClass="Test\AppBundle\Repository\CRepository") 
*/ 
class C 
{ 
    /** 
    * @var 
    * @ORM\OneToMany(targetEntity="A", mappedBy="c", cascade={"all"}) 
    */ 
    private $as = null; 
} 

回答

1

我不知道這一個內置的解決方案(且有教義沒有最好的做法無論是),但這裏有一些想法可以幫助你:

1.使用getter/setter方法爲 「空」 的$ B協會,如果$ C被設置,反之亦然

應該是這樣的:

public function setB($b) { 
    $this->b = $b; 
    if($b !== null) { 
     $this->c = null; 
    } 
} 

優點是它不會對於您的實體可能有一個無效的狀態,其中$ b和$ c都被設置。然而,教條正在使用反射如果實體實例是從持久對象創建的,以防止__construct調用。它可能可能是也有一個setter方法的原因,所以你的實體進入一個不想要的狀態,但我不能否定我的指控(也許是爲了防止某種骯髒的狀態)。

此外,您可以將此視爲您A類的用戶可能不需要的副作用(尤其是在您不希望發生此問題的簡單設置器方法中)。這是你必須在你的上下文中詳細說明的。

此解決方案與symfony表單無關。只要性能不公開,形式系統will call the setter methods

除非屬性是公共的,它必須有一個「getter」和「二傳手」的方法,以便表單組件可以得到,並把數據放到屬性。

2.使用生命週期回調

我會去這個方法親自擔任我認爲這是比較容易理解。(見documentation)使用

例prePersist:

/** 
* @ORM\PrePersist 
* @ORM\PreUpdate 
*/ 
public function checkAssociations() 
{ 
    if($this->a !== null && $this->b !== null) { 
     // throw some error 
    } 
} 

此代碼是

  • 更好可讀(IMO),因爲它是更 「明文樣」(「如果A和B兩者拋出錯誤「)比解決方案解決方案
  • 更少的錯誤傾向(不保證您的設置方法被調用)

希望有幫助。

如果有人對symfony中的setter調用有更多的信息,那會很棒。

+0

謝謝,我想我會用生命週期回調,因爲基於setters的方法確實更容易出錯(比如設置一件事,然後另一件事 - 並想知道爲什麼最終會出現錯誤的設置) –

相關問題