Symfony2和Doctrine findOneById()而不加载关联的实体?

时间:2015-07-08 05:33:39

标签: php entity-framework symfony doctrine-orm

是否可以使用findOneById()获取实体而不加载其关联实体?在某些情况下,例如只检查实体是否存在,我不需要加载所有相关实体,例如,

$entity = $em->getRepository('EstateBundle:MyEntity')->findOneById($id);
if (!$entity) {
    throw $this->createNotFoundException('Unable to find the entity.');
}

否则,我认为这可能导致性能问题。 In CakePHP, it is possible using an option recursive。我在Symfony和Doctrine中寻找这样的选择。我认为这是一个常见的问题,但我找不到任何关于此的文档。

2 个答案:

答案 0 :(得分:1)

编辑:删除了getReference的可能性,因为它不是问题的解决方案。

第二种可能性是通过fetch="EXTRA_LAZY"更改您的实体 Doctrine extra lazy

一般情况下:您的关联实体默认选择为LAZY,表示只在首次访问时才加载。也许你的问题首先不相关? 确保使用Symfony的开发模式。在那里,您可以选择查看实际执行的数据库查询。

编辑:  然后,您可以使用getRepository("bundle:entity")->find($id)来检查是否存在。  对于实际查询它写一个方法,如:

$q = $this->createQueryBuilder('o,u,i')
        ->select('o')
        ->from("bundle:entity","o")
        ->leftJoin("o.prop","u")
        ->leftJoin("o.prop2","i")
        ->where('o.id = :id')
        ->setParameter('id', $id)
        ->getQuery();

然后它也会获取其他实体。

希望有所帮助

答案 1 :(得分:0)

默认情况下,如果执行findOneBy(),Doctrine将只获取一个包含其所有数据的实体,而不是关系。如果你真的想检查实体是否存在,请添加一个select(' id')语句,这样你的对象就会很小(id就会被水化了)。

然后,如果你的对象有关系,如果你做$ your_object-> relations()。 Doctrine将延迟加载导致额外查询的关系。

为防止这种情况发生,您可以通过创建自己的方法来禁止Doctrine的延迟加载:

 public function findMyObjectById($id)
    {
        $q = $this->createQueryBuilder('o')
            ->select('o.id')
            ->where('o.id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);

        return ($q->getResult());
    }