教义:选择一个不受教义管理的表

时间:2019-01-31 13:57:00

标签: symfony doctrine-orm

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

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

DQL中的结果如下:

ImageRepository.php

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

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

AboutPage.php (即创建连接表的实体)

  /**
     * @var Image[]|ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="App\Entity\Image", cascade={"persist", "remove"})
     * @ORM\JoinTable(name="about_images",
     *     joinColumns={@ORM\JoinColumn(name="about_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="image_id", referencedColumnName="id", unique=true)})
   */
    private $images;

“图像”实体中的字段:

    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=255)
     */
    private $image;

    /**
     * @var File
     *
     * @Vich\UploadableField(mapping="collection_images", fileNameProperty="image")
     * @Assert\File(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
     *
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $imageAlt;

    /**
     * @var DateTime
     *
     * @ORM\Column(type="datetime")
     */
    private $updatedAt;

    /**
     * @var string
     *
     * @ORM\Column(type="string", nullable=true)
     */
    private $alt;

如何解决此问题?结果应为Image个实体。

2 个答案:

答案 0 :(得分:3)

您可以编写本机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-entities数组,其中包含所有可用的图像实体(但相关实体)。

答案 1 :(得分:0)

目前尚不清楚带有提供的代码的示例sql,但是如果您在实体中定义了关系,则只需告诉实体的关系字段,就可以将它们与查询构建器连接起来,所以我认为这应该工作

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

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

请始终记住,您必须在实体中使用字段名(通常为cameCasedStyle),而不是在数据库表中使用列名(通常为snake_cased_style)。