Symfony Doctrine ORM ManyToMany - 带有标签的博客 - 我没有从博客中获取所有标签,没有延迟加载

Posted

技术标签:

【中文标题】Symfony Doctrine ORM ManyToMany - 带有标签的博客 - 我没有从博客中获取所有标签,没有延迟加载【英文标题】:Symfony Doctrine ORM ManyToMany - blog with tags - i dont get all tags from blog, without lazy load 【发布时间】:2016-02-22 06:12:56 【问题描述】:

manyToMany 上的 Doctrine 延迟加载。

我在我的博客(帖子)中使用Application\Sonata\ClassificationBundle\Entity\Tag

/**
     * @var string
     *
     * @ORM\ManyToMany(targetEntity="\Application\Sonata\ClassificationBundle\Entity\Tag", cascade="persist" )
     * @ORM\JoinTable( name="blog__post_tag" , 
     * joinColumns= @ORM\JoinColumn( name="blog_post_id", referencedColumnName="id" ),
     * inverseJoinColumns= @ORM\JoinColumn( name="tag_id", referencedColumnName="id" )
     * )
     */
    private $tags;

工作代码:

$q = $this->createQueryBuilder('p')
                ->select('p')
                ->innerJoin('p.tags', 't')
                ->where('t = :name')->setParameter('name', $tag)
                ->andWhere('p.isActive = :active')->setParameter('active', TRUE)
                ->orderBy('p.id', 'DESC');
        return $q->getQuery();

从这个输出查询中,我在树枝中使用标签。所以我必须选择帖子和标签。如果我将代码更新为:

$q = $this->createQueryBuilder('p')
                ->select('p', 't')
                ->innerJoin('p.tags', 't')
                ->where('t = :name')->setParameter('name', $tag)
                ->andWhere('p.isActive = :active')->setParameter('active', TRUE)
                ->orderBy('p.id', 'DESC');
        return $q->getQuery();

我只得到一个标签。

信息:

工作代码使用更多 db 查询(1 个查询)。 更新的代码有效(不再查询)。但结果我得到了所有帖子只有一个标签

示例:

“我的第一篇文章”有标签 ['one','two','three']。 “我的第二篇文章”有标签 ['two']。

当我使用第一个查询时。工作正常。但是标签的学说延迟加载代码。我得到 (query1) two = "My First post" 的输​​出有标签 ['one','two','three']。 , “我的第二篇文章”有标签 ['two']。

当我使用第二个查询时。 (query2) two = "My First post" 的输​​出有标签 ['two']。 , “我的第二篇文章”有标签 ['two']。

我需要帖子中的所有标签。目前我从帖子中只得到一个标签。

【问题讨论】:

【参考方案1】:

因为 INNER JOIN 就是这样。关于连接类型的好答案在这里:https://***.com/a/6188334/919567

这个版本的查询适合你:

$q = $this->createQueryBuilder('p')
    ->select('p', 't')
    ->leftJoin('p.tags', 't')
    ->where('t = :name')->setParameter('name', $tag)
    ->andWhere('p.isActive = :active')->setParameter('active', TRUE)
    ->orderBy('p.id', 'DESC');

return $q->getQuery();

【讨论】:

【参考方案2】:

Sudhakar K,如果这对你有用,你绝对应该使用 Pawel 的答案 - 我怀疑它会,但仍然如此。

这里的问题是您无法在少于 2 个请求中获得您正在寻找的结果,因为您正在尝试同时做 2 件事:

    查找与特定Tag 相关的所有Post 实体 查找与找到的Post 实体相关的所有Tag 实体

...以及所有具有相同连接的所有内容,这似乎完全不可能。由于您对要检索的 Tag 施加了条件,因此唯一检索到的 Tag 实体将是满足该条件的实体,即具有您搜索的名称的 Tag

您必须对同一个表进行多次连接才能使其正常工作,即使这样我也怀疑它是否会按照您想要的方式工作。

请记住,Doctrine 的设计目的在于易用性而非性能。在使用 Doctrine IMHO 时,试图以这种方式阻止低成本的单个附加请求会适得其反。

知道这一点,我强烈建议您使用第一个解决方案。

【讨论】:

嘿 Zephyr,你能指点我参与查询 Sudhakar 在哪里找到与找到的 Post 相关的所有 Tag 实体? 嗯,根据他的 DQL 请求,他不是。但根据他的问题,这是他试图做的。

以上是关于Symfony Doctrine ORM ManyToMany - 带有标签的博客 - 我没有从博客中获取所有标签,没有延迟加载的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?

级联持久性不工作(Doctrine ORM + Symfony 2)

如何在 symfony 中更新新版本的 Doctrine2 和 ORM?

Symfony 3 Doctrine MySQL - 使用 @ORM 注释生成实体

Symfony2 Doctrine ORM 安装配置

ORM Doctrine ManyToOne on update CASCADE (Symfony)