【问题标题】:Symfony 4/Doctrine 2 - fetching real object not the proxySymfony 4/Doctrine 2 - 获取真实对象而不是代理
【发布时间】:2020-04-04 11:48:09
【问题描述】:

我有以下实体:

/**
 * @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 的 ManyToOne 关系指向它的父级。

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

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" 不会改变任何东西:(

【问题讨论】:

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

标签: php symfony doctrine-orm symfony4 many-to-one


【解决方案1】:

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

查看文档here

来自文档的示例:

// 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 将返回真正的 Category 对象,因为不需要延迟加载。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-31
    • 2012-01-10
    • 2019-01-29
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    相关资源
    最近更新 更多