2012-05-12 104 views
1

我試圖根據名爲Account的關聯實體的屬性過濾「客戶」實體列表。問題是Account實體只是一個基類,過濾的實際屬性存在於它們的子實體(PersonalAccount和EnterpriseAccount)中,但是Doctrine只讓我訪問Account基類的屬性。Symfony2 + Doctrine2:根據繼承關係的屬性過濾實體

總之,這裏是我的情況:

客戶實體:

class Client 
{ 
    /** @ORM\OneToMany(targetEntity="Account", mappedBy="client") */ 
    protected $accounts; 
} 

的基本帳戶實體:

class Account 
{ 
    /** @ORM\ManyToOne(targetEntity="Client", inversedBy="accounts") */ 
    protected $client; 
} 

PersonalAccount實體(帳戶兒童)

class PersonalAccount extends Account 
{ 
    /** @ORM\Column() */ 
    protected $name; 
} 

在我的控制器中,我嘗試過:

$qb = $em->getRepository('MyBundle:Client')->createQueryBuilder('cl'); 

$query = $qb->select('cl') 
      ->innerJoin('cl.accounts', 'acc') 
      ->where('acc.name = :name') 
      ->setParameter('name', 'Jhon') 
      ->getQuery(); 

但它會拋出一個異常,因爲基類Account沒有名爲「name」的屬性。

如何使用繼承的PersonalAccount類的屬性過濾客戶端實體?

回答

3

首先,你應該在你的父類中添加一些繼承註釋。 您應該從Doctrine doc中閱讀這篇文章:6. Inheritance Mapping

事實上,繼承是遞增的,而不是遞減的。

「訪問超類,並檢查該對某個孩子存在一個屬性是不可能在沒有具體的鑄造入式事先進行嚴格的面向對象的語言。」

您需要的功能正在討論here

:你可以暫時做什麼用類表繼承和這樣的事情:

$qb = $em->getRepository('MyBundle:Client')->createQueryBuilder('cl'); 
$qb2 = $em->getRepository('MyBundle:PersonalAccount')->createQueryBuilder('persoAcc'); 

$query = $qb->select('cl') 
      ->where(
       $qb->expr()->in(
        'cl.id', 
        $qb2->select('persoAcc.id') 
         ->where('persoAcc.name = :name') 
         ->setParameter('name', 'Jhon') 
         ->getDql() 
       ) 
      ) 
      ->getQuery(); 

而且我會建議你使用存儲庫類。

+0

這就是我一直在尋找的!事實上,我在代碼中有必要的繼承註釋,但是我並沒有在這個例子中寫出它,只是爲了儘量減少代碼。非常感謝你。 –

1

在客戶端加入一個協會:

/** @ORM\OneToMany(targetEntity="PersonalAccount", mappedBy="client") */ 
protected $personalAccounts; 

,做它的加入:

->innerJoin('cl.personalAccounts', 'acc') 
+0

感謝您的回答,但在我的情況下,這種方式並不合適,因爲客戶實體可以擁有PersonalAccount和/或EnterpriseAccount,因此將其鏈接到父帳戶實體是有意義的。 –

相關問題