给定以下实体:
class Entity {
protected $id;
}
class User extends Entity {
/** @var Entity */
protected $target;
}
class Document extends Entity {
protected $title;
}
class Report extends Entity {
protected $level;
}
我需要创建什么映射才能使条令正确映射User
实体。这里的问题是,我希望User::$target
能够使用任何实体(因此Entity
类型提示),并且稍后在代码中能够做出相应的响应,这取决于它是Document
还是Report
。
这也意味着,在代码中,如果它是Document
,我需要能够获取Entity::$title
;如果是Report
,我需要获取Entity::$level
。
我能用教义做到这一点吗?
这应该可以正常工作。我没有添加默认注释,如"@ORM\Entity"(http://docs.doctrine-project.org/en/latest/reference/annotations-reference.html)。我希望这就是你想要的,否则请告诉我。
/**
* @ORMInheritanceType("SINGLE_TABLE")
*/
class Entity {
protected $id;
}
class User extends Entity {
/**
* @ORMManyToOne(targetEntity="Entity")
* @var Entity
*/
protected $target;
}
看看:http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html由于性能问题,您应该使用单一继承而不是类表继承。
否则,Doctrine将对实体表的子表进行联接,因为Doctrine不知道"实体"具有哪种类型。类似于:
SELECT t1.id, t2.title, t3.level FROM entity t1 LEFT JOIN document t2 ON t2.id = t1.id LEFT JOIN report t3 ON t3.id = t1.id
更多的子表将导致更多的联接->较慢。
这就是您如何检查目标是文档还是报告,并确定您必须访问的字段。
// loads all users
$users = $this->em->getRepository('User')->findAll();
foreach($users as $user){
$target = $user->getTarget()
if($target instanceof Document){
echo $target->getTitle();
}
else if($target instanceof Report){
echo $target->getLevel()
}
}