原则:选择不受原则管理的表



使用Doctrine QueryBuilder,我想执行一个查询,它在本机SQL中如下所示:

`SELECT image FROM image i INNER JOIN about_images a ON i.id = a.image_id`;

DQL 中的结果如下所示:

图像存储库.php

return $this->createQueryBuilder('i')
        ->select('i')
        ->innerJoin('about_images', 'a', 'WITH', 'i.id = a.imageId')
        ->getQuery()
        ->getResult();

其中image是实体,about_images是联接表(@ManyToMany关系的结果)。但是,我得到一个错误,即about_images没有定义,这是有道理的,因为它不受教义管理。

关于页面.php(即创建联接表的实体)

  /**
     * @var Image[]|ArrayCollection
     *
     * @ORMManyToMany(targetEntity="AppEntityImage", cascade={"persist", "remove"})
     * @ORMJoinTable(name="about_images",
     *     joinColumns={@ORMJoinColumn(name="about_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORMJoinColumn(name="image_id", referencedColumnName="id", unique=true)})
   */
    private $images;

图像实体中的字段:

    /**
     * @var int
     *
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     */
    private $id;
    /**
     * @var string
     *
     * @ORMColumn(type="string", length=255)
     */
    private $image;
    /**
     * @var File
     *
     * @VichUploadableField(mapping="collection_images", fileNameProperty="image")
     * @AssertFile(maxSize="150M", mimeTypes={"image/jpeg", "image/jpg", "image/png", "image/gif"},
     *     mimeTypesMessage="The type ({{ type }}) is invalid. Allowed image types are {{ types }}")
     */
    private $imageFile;
    /**
     * @var string
     *
     * @ORMColumn(type="string", length=255, nullable=true)
     */
    private $imageAlt;
    /**
     * @var DateTime
     *
     * @ORMColumn(type="datetime")
     */
    private $updatedAt;
    /**
     * @var string
     *
     * @ORMColumn(type="string", nullable=true)
     */
    private $alt;

如何解决这个问题?结果应该是Image实体。

您可以编写本机 SQL,然后使用 ResultSetMapper 将输出映射到实体。

对于您的示例,它在存储库类中可能如下所示:

public function findImagesWithAboutImages()
{
    $sql = 'SELECT i.* FROM image i INNER JOIN about_images a ON i.id = a.image_id';
    $entityManager = $this->getEntityManager();
    $mappingBuilder = new ResultSetMappingBuilder($entityManager);
    $mappingBuilder->addRootEntityFromClassMetadata(Image::class, 'i');
    $query = $entityManager->createNativeQuery($sql, $mappingBuilder);
    // If you want to set parameters e.g. you have something like WHERE id = :id you can do it on this query object using setParameter()
    return $query->getResult();
}

如果需要相关数据,则必须将其添加到带有别名的 select 子句中,然后使用 $mappingBuilder->addJoinedEntityFromClassMetadata() 将这些字段分配给连接的实体,就像上面使用根实体一样。

实体中的注释已经定义了每个字段如何映射到属性以及它的类型,因此基本上您应该获得一个 Image-entity 数组,其中包含加载的所有内容(但相关实体)可用。

示例

sql与您提供的代码不是很清楚,但是如果您在实体中定义了关系,则只需告诉实体的关系字段即可将它们与查询生成器连接起来,所以我认为这应该可以工作

return $this->createQueryBuilder('i')
    ->select('i')
    ->innerJoin('i.images', 'a')
    ->getQuery()
    ->getResult();

由于您已经在实体中定义了关系,因此 Doctrine 知道如何连接您的表,因此您只需指定关系字段名称和别名。

并且永远记住,您必须在实体中使用字段名称(通常为 cameCasedStyle),而不是数据库表中的列名(通常snake_cased_style)。

相关内容

  • 没有找到相关文章

最新更新