我有一个Person
和Admin
实体。一个Person
只能有一个Admin
,但是我并不需要一直保持管理员状态。当我列出所有与admin相关的人员时,该学说将从DB中加载所有管理员。为什么会这样?
答案 0 :(得分:0)
在一对一关联的情况下(和类似的情况,例如,在延迟加载一对多关联的情况下),Doctrine为关联实体生成所谓的proxy objects。这些代理对象模仿目标实体的界面,但仅在访问 non-id 字段时才触发从数据库加载实际数据。
由于这种情况,当您获取Person
个实体的列表时-您不会获得从数据库中获取的Admin
个实体的列表,但会收到Admin
个代理的列表代替。除非您(偶尔或有意)尝试访问Admin
实体的某些属性(可以安全访问的id
实体除外),Doctrine不会尝试获取任何Admin
信息来自数据库。
请考虑以下简化的设置,以A
和B
实体进行一对一关联:
// A.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
*/
class A
{
/**
* @var integer
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var B
* @ORM\OneToOne(targetEntity="App\Entity\B")
*/
private $b;
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return B
*/
public function getB(): B
{
return $this->b;
}
}
// B.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
*/
class B
{
/**
* @var integer
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string|null
* @ORM\Column(type="string", nullable=true)
*/
private $name;
}
通过查看调试器或使用反射,可以证明A::$b
包含代理对象:
$entities = $this->getEntityManager()->getRepository(\App\Entity\A::class)->findAll();
/** @var \App\Entity\A $a */
$a = array_shift($entities);
$class = (new \ReflectionObject($a->getB()))->getName();
在这种情况下,$class
变量的值将是Proxies\__CG__\App\Entity\B
(App\Entity\B
的Doctrine代理对象),而不是正常实体对象的App\Entity\B