Используя 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 не определен, что имеет смысл, поскольку он не управляется доктриной.
О странице.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.
@dbrumann За документацией действительно непросто следить, и я не смог найти четких примеров в Интернете. Я был бы признателен за некоторые рекомендации. Дайте мне знать, если вам нужна дополнительная информация о моем объекте Image. Спасибо.
Пожалуйста, опубликуйте свой класс App\Entity\Image (свойство about_pages). Кстати, это можно сделать... $entityManager->getRepository(AboutPage::class)->createQueryBuilder("a")->join("a.images", "i")
@SilvioQ Я обновил свой вопрос кодом, который вы запросили. В моем объекте aboutPage нет свойства Image. На изображения ссылаются через таблицу соединений, поэтому мне нужен доступ к этой таблице соединений.
ммм... Image::class ничего не знает о AboutPage::class... как насчет $entityManager->getRepository(AboutPage::class)->createQueryBuilder("a")->join("a.images", "i")->select("a,i")




Вы можете написать собственный 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(), чтобы назначить эти поля объединенному объекту, как и выше с корневым объектом.
Ваши аннотации в вашей сущности уже определяют, как каждое поле сопоставляется со свойством и какой у него тип, поэтому в основном вы должны получить массив изображений-сущностей со всем (кроме связанных сущностей), загруженным для использования.
Есть идеи, почему этот код выдает TableNotFoundException: Unknown table image? Протестировал его с помощью необработанного запроса, и он дал мне правильные результаты без исключения. Классы также правильно импортированы. Спасибо за старания.
Я пропустил псевдоним в FROM, возможно, это он. Попробуйте SELECT i.* и также в addRootEntityFromClassMetadata замените image на i. Я также обновил ответ.
Работал как шарм. Спасибо.
Не совсем ясен пример sql с предоставленным вами кодом, но если у вас есть отношение, определенное в ваших объектах, вы можете присоединиться к ним с помощью построителя запросов, просто указав поле отношения объекта, поэтому я думаю, что это должно работать
return $this->createQueryBuilder('i')
->select('i')
->innerJoin('i.images', 'a')
->getQuery()
->getResult();
Поскольку вы уже определили свои отношения в своих сущностях, Doctrine знает, как соединить ваши таблицы, поэтому вам просто нужно указать имя поля отношения и псевдоним.
И всегда помните, что вы должны использовать имя поля в своей сущности (обычно cameCasedStyle), а не имя столбца в таблицах вашей базы данных (обычно змея_cased_style).
Вы можете использовать собственный запрос (SQL), а затем использовать RSM для сопоставления полей, возвращаемых результатом, с вашей сущностью. См.: doctrine-project.org/projects/doctrine-orm/en/2.6/reference/… Не стесняйтесь следить, если документы неясны или вы застряли в реализации этого, и я могу написать более подробный ответ.