Php Symfony 4/2原则-获取真实对象而不是代理

Php Symfony 4/2原则-获取真实对象而不是代理,php,symfony,doctrine-orm,symfony4,many-to-one,Php,Symfony,Doctrine Orm,Symfony4,Many To One,我有以下实体: /** * @ORM\Entity(repositoryClass="App\Repository\CourseLevelRepository") */ class CourseLevel { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @var CourseLe

我有以下实体:

/**
 * @ORM\Entity(repositoryClass="App\Repository\CourseLevelRepository")
 */
class CourseLevel
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var CourseLevel
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\CourseLevel", fetch="EAGER")
     * @ORM\JoinColumn(nullable=true, referencedColumnName="id")
     */
    private $nextCourseLevel;   


    ...
}
正如您所见,它构建了一个树结构,因此任何记录都可以通过$nextCourseLevel的多个关系指向它的父项

然后,我使用存储库中的查询获取元素列表:

class CourseLevelRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, CourseLevel::class);
    }

    public function fetchFiltered(array $filters)
    {
        $builder = $this->createQueryBuilder('cl');
        $builder->setFirstResult(0);
        $builder->setMaxResults(10)
        $builder->orderBy('cl.name', 'asc');

        return $builder->getQuery()->getResult();
    }
}
让我们假设以下一组数据:

id | next_course_level
-------------------------
1  | 2
2  | null
为此,我将接收以下对象: -id=1的对象,它是App\Entity\CourseLevel的对象(将$nextCourseLevel设置为对象id=2,它是一个代理) -id为2的对象,它是代理对象

这可能是因为id=1的关系对象指向id=2作为父对象


但是,我如何强制将所有数据作为真实对象而不是代理来获取呢?放置fetch=“EAGER”不会改变任何东西:(

您必须加入并选择您的关联才能获取对象而不是代理

检查文档

文档中的示例:

// src/Repository/ProductRepository.php
public function findOneByIdJoinedToCategory($productId)
{
$entityManager = $this->getEntityManager();

$query = $entityManager->createQuery(
    'SELECT p, c
    FROM App\Entity\Product p
    INNER JOIN p.category c
    WHERE p.id = :id'
)->setParameter('id', $productId);

return $query->getOneOrNullResult();
}

“当您一次检索所有产品和类别数据(通过联接)时,Doctrine将返回真正的类别对象,因为不需要延迟加载任何内容。”

我们可以知道为什么会出现这种用例吗?为什么需要“真正的对象”而不是代理?代理仍然是一个真实的对象,它只是扩展了你的实体,因此它对你的应用程序来说应该是短暂的。我用我的自定义注释注释了CourseLevel的一些字段,并进一步基于该注释处理对象。有了对象的代理,我有这样的数据,但我没有注释了。哈哈您首先不能解析批注。您可以从实体管理器完全访问实体的类元数据。