我有一个实体,比如Person,其中包含$pets
的列表:
protected $pets;
public function getPets()
{
return $this->pets;
}
标准学说。不幸的是,这些宠物可能是不同类型的,例如猫或狗,或混合物。所以我使用了Class Table Inheritance:
/**
* @ORM\Entity
* @ORM\Table(name="pets")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="pettype", type="string")
* @ORM\DiscriminatorMap({"cat_animal" = "CatAnimal", "dog_animal" = "DogAnimal"})
*/
class Pet
{
/**
* @ORM\Column(name="eventid", type="integer")
* @ORM\Id
*/
private $id; // protected did not work either
/**
* Get id
*/
public function getId()
{
return $this->id;
}
}
/**
* @ORM\Entity
* @ORM\Table(name="cat_animal")
*/
class CatAnimal extends Pet
{
/**
* @ORM\Column(type="float")
*/
protected $height;
// etc.
}
// DogAnimal class omitted.
使用Doctrine's docs这是相对简单的。
如果我想让一个人获得所有猫,我发现我可以这样做:
public function getCats($person)
{
return $this->getEntityManager()->getRepository('MyBundle:CatAnimal')
->findByPerson($person);
}
但是,如何使用查询构建器访问子类?如果我有Person存储库($ repos here),我想做类似以下的事情:
$repos->createQueryBuilder('person')
->select('pet.height')
->join('person.pets', 'pet')
->where('person = :person')
->setParameter('person', $person);
除了宠物没有身高,所以这会引发异常。生成的DQL自动连接到DogAnimal和CatAnimal,所以我应该能够访问这些属性,但我不知道如何。我试过了:
$repos->createQueryBuilder('person')
->select('cat.height')
->from('MyBundle:CatAnimal', 'cat)
->join('person.pets', 'pet')
->where('person = :person')
->setParameter('person', $person);
但这似乎是笛卡尔积。我可以通过添加:
来解决这个问题->andWhere('person.id = cat.person')
对于我想要的东西,这似乎过于复杂。我一直试图寻找正确的方法,但资源有限。
这基于previous question,具有类似的结构。为了清晰和普遍性,更改了表格的名称。
答案 0 :(得分:1)
您需要正确加入Person
,向Pet
课程添加字段。在我的例子中,我将其命名为owner
:
$catRepo->createQueryBuilder('cat')
->select('cat.height')
->from('MyBundle:CatAnimal', 'cat')
->join('cat.owner', 'person')
->where('person = :person')
->setParameter('person', $person);