Doctrine - 从反面查询一对多、单向的连接表关联

Posted

技术标签:

【中文标题】Doctrine - 从反面查询一对多、单向的连接表关联【英文标题】:Doctrine - Query One-To-Many, Unidirectional with Join Table association from inversed side 【发布时间】:2016-04-10 23:42:59 【问题描述】:

我的目标是:

创建通用关联,其中第一个实体(例如类别)可以多次用于其他对象(例如帖子、文章)

示例

Post 有分类,Article 有分类,但是 Article 和 Post 是完全不同的实体。 (两者不能同时连接)


映射示例:

发帖

<?php
/** @Entity */
class Post

    // ...

    /**
     * @ManyToMany(targetEntity="Category")
     * @JoinTable(name="post_categories",
     *      joinColumns=@JoinColumn(name="post_id", referencedColumnName="id"),
     *      inverseJoinColumns=@JoinColumn(name="category_id", referencedColumnName="id", unique=true)
     *      )
     */
    private $categories;

    public function __construct()
    
        $this->categories= new \Doctrine\Common\Collections\ArrayCollection();
    

    // ...

文章

<?php
/** @Entity */
class Article

    // ...

    /**
     * @ManyToMany(targetEntity="Category")
     * @JoinTable(name="article_categories",
     *      joinColumns=@JoinColumn(name="article_id", referencedColumnName="id"),
     *      inverseJoinColumns=@JoinColumn(name="category_id", referencedColumnName="id", unique=true)
     *      )
     */
    private $categories;

    public function __construct()
    
        $this->categories= new \Doctrine\Common\Collections\ArrayCollection();
    

    // ...

类别

<?php
/** @Entity */
class Category

    // ...
    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $name;

如您所见,这是一对多、单向和连接表关联。 现在有了这个我可以查询单个Post 类别和Article 类别,但类别不知道帖子或文章。这很好,因为我可以重复使用Category


哪里出了问题?

我需要加载 ALL PostsArticles,其中包含单个 CategoryCategories

示例

我们有 20 个类别名为 "symfony"(id:2) 的帖子和 10 个类别名为 "doctrine"(id:3) 的帖子。现在我需要查询以加载所有类别为"doctrine"的帖子

findPostsByCategoryId( $id );
// findPostsByCategoryId( 3 );

所有具有两个类别的帖子

findPostsByCategories( Array $array );
// findPostsByCategories( array(2,3) );

我该怎么做?

我需要这个案例的解决方案或解决方案来实现我的目标。 每个提示都值得赞赏。

附注我对这里描述的这个映射还有其他相关问题

Validate UniqueEntity for One-To-Many, Unidirectional with Join Table

【问题讨论】:

您似乎走在了正确的轨道上 - 您是遇到错误还是没有收到您正在寻找的信息? 是的,错误,但我无法创建没有警告和“您正在寻找的信息”的有效查询:) 您能发布您收到的实际警告吗? 例如:“错误:如果不选择至少一个根实体别名,就无法通过标识变量选择实体。”但我认为即使没有错误,我的查询也不会加载我想要的内容 您最好的方法是创建自定义存储库函数,使用 QueryBuilder 或 DQL 来获取您需要的内容。听起来您可能从错误的根别名中进行选择,如果没有看到您发布的完整代码,很难确定。 【参考方案1】:

除非我误读了您的问题,否则这似乎很简单:

获取特定类别的所有帖子:

$qb = $this->getEntityManager()->createQueryBuilder();

$qb->select('p')
    ->from('SomeBundle:Post', 'p')
    ->join('p.categories', 'c')
    ->where('c.id = :categoryId')
    ->setParameter('categoryId', $categoryId)
    ->getQuery()
    ->getResult();

获取具有一系列类别的所有帖子:

$qb = $this->getEntityManager()->createQueryBuilder();

$qb->select('p')
    ->from('SomeBundle:Post', 'p')
    ->join('p.categories', 'c')
    ->where($qb->expr()->in('c.id', ':categoryIds'))
    ->setParameter('categoryIds', $categoryIds) // array of ids
    ->getQuery()
    ->getResult();

【讨论】:

以上是关于Doctrine - 从反面查询一对多、单向的连接表关联的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine 对一对多关系进行了许多查询

Doctrine2 - 无法删除具有单向 oneToMany 关系的实体

关于与查询构建器的“一对多”关系的教义内连接

如何避免在一对多单向关联中插入和更新查询

Symfony 2 与 Doctrine 中的一对多关系

原则 3:一对一的单向关系不会返回所有字段