Doctrine2:加载main后填充相关实体

时间:2011-08-10 19:38:56

标签: lazy-loading doctrine-orm

HotelCommentCommentPhoto(1:n) - 用户可以将一些照片添加到自己的评论中。我正在使用一个查询加载评论片段,并希望使用其他查询将照片加载到此评论中(使用WHERE IN)。

$comments = $commentsRepo->findByHotel($hotel);
$comments->loadPhotos(); // of course comments is simple array yet

根据需要加载评论,而不是PostLoad事件。

所以问题是:如何将加载的评论与HotelComment的对象相关联?使用ReflectionPropertysetAcesseble() + setValue()?有更简单的溶解吗?我担心UoW检测到HotelComment个实体已被修改,并会向db发送更新。

2 个答案:

答案 0 :(得分:0)

您必须将关系配置为“LAZY”。请参阅学说文档:

  1. ManyToOne
  2. ManyToMany
  3. OneToOne
  4. 您可以使用$comments->loadPhotos()懒散地加载它,至少文档says so

    更新:我认为你不需要特别的东西来避免你的实体刷新到数据库。事实上,当您使用DQL查询条目时,它们具有managed状态,因此将它们附加到其他管理实体的集合不会更改其状态,因此除非您已修改它们,否则不会刷新它们。

    Hovewer,完全没有帮助,因为在第一次使用之前获取了关联,因此使用以下代码向集合中添加实体将导致隐式数据库查询:

    $comment->addPhoto($photo);
    //in Comment class
    function addPhoto(Photo $photo){
        //var_dump(count($this->photos)); //if you have any - they are already here
        $this->photos->add($photo);
    }
    

    也许宣称你的收藏是公开的(或者ReflectionProperty的伎俩)会帮助愚弄教条,但这是一个肮脏的黑客,所以我甚至都没有尝试过。

    分离父实体也没有帮助。我现在已经没想完了......

答案 1 :(得分:0)

如果你只需要一次水化相关对象,而不是每次加载对象时都需要使用DQL:

$em->createQuery("SELECT comments, photos FROM HotelComment comments JOIN comments.photos photos");

您可以将其放在存储库中的方法中。 这将发出一个SELECT语句,其中INNER JOIN到评论照片表。