Проблема QueryBuilder с JOIN

у меня проблема с Doctrine queryBuilder. У меня есть две сущности: пожертвования и пожертвования. Я просто хочу сделать левое соединение (например, потому что Donations.donorId ссылается на Donateurs.id).

Запрос в DonationsRepository:

public function showAll()
    {
        $qb = $this->createQueryBuilder('dr')
            ->select('dr, dn')
            ->leftJoin('dr.donateurs','dn')
            ->getQuery()
            ->execute();

        return $qb;
    }

Вызовите мой Controller.php:

public function don(DonationsRepository $repo, Request $request)
    {
        $qb = $repo->showAll();
        var_dump($qb);

        // Then return to Twig
    }

Вот пример var_dump:

array (size=14)
  0 => 
    object(App\Entity\Donations)[989]
      private 'id' => int 197
      private 'movement' => string 'D' (length=1)
      private 'departDate' => 
        object(DateTime)[885]
          public 'date' => string '2023-11-18 00:00:00.000000' (length=26)
          public 'timezone_type' => int 3
          public 'timezone' => string 'Europe/Paris' (length=12)
      private 'certifDate' => 
        object(DateTime)[993]
          public 'date' => string '2023-11-18 00:00:00.000000' (length=26)
          public 'timezone_type' => int 3
          public 'timezone' => string 'Europe/Paris' (length=12)
      private 'certifRef' => string 'EO62' (length=4)
      private 'productName' => string 'Clémentines' (length=12)
      private 'donorId' => int 1
      private 'family' => string 'Frais' (length=5)
      private 'recipient' => string 'EO62' (length=4)
      private 'carrierId' => int 3
      private 'nbPallet' => int 33
      private 'weight' => int 19720
      private 'billDate' => 
        object(DateTime)[891]
          public 'date' => string '2023-11-18 00:00:00.000000' (length=26)
          public 'timezone_type' => int 3
          public 'timezone' => string 'Europe/Paris' (length=12)
      private 'billReceptionDate' => 
        object(DateTime)[992]
          public 'date' => string '2023-11-18 00:00:00.000000' (length=26)
          public 'timezone_type' => int 3
          public 'timezone' => string 'Europe/Paris' (length=12)
      private 'billSentValidationDate' => 
        object(DateTime)[991]
          public 'date' => string '2023-11-18 00:00:00.000000' (length=26)
          public 'timezone_type' => int 3
          public 'timezone' => string 'Europe/Paris' (length=12)
      private 'billReference' => string '23-11-18' (length=8)
      private 'price_HT' => int 11
      private 'donateurs' => null

Все данные только от моих объектов пожертвований.... НО, если я удалю execute() из моего репозитория и сделаю $qb->execute с моего контроллера... var_dump верните мне что-то подобное (это пример, дамп слишком большой)

var_dump($qb) :

public 'declaringClasses' => 
        array (size=32)
          'id_0' => string 'App\Entity\Donations' (length=20)
          'movement_1' => string 'App\Entity\Donations' (length=20)
          'depart_date_2' => string 'App\Entity\Donations' (length=20)
          'certif_date_3' => string 'App\Entity\Donations' (length=20)
          'certif_ref_4' => string 'App\Entity\Donations' (length=20)
          'product_name_5' => string 'App\Entity\Donations' (length=20)
          'donor_id_6' => string 'App\Entity\Donations' (length=20)
          'family_7' => string 'App\Entity\Donations' (length=20)
          'recipient_8' => string 'App\Entity\Donations' (length=20)
          'carrier_id_9' => string 'App\Entity\Donations' (length=20)
          'nb_pallet_10' => string 'App\Entity\Donations' (length=20)
          'weight_11' => string 'App\Entity\Donations' (length=20)
          'bill_date_12' => string 'App\Entity\Donations' (length=20)
          'bill_reception_date_13' => string 'App\Entity\Donations' (length=20)
          'bill_sent_validation_date_14' => string 'App\Entity\Donations' (length=20)
          'bill_reference_15' => string 'App\Entity\Donations' (length=20)
          'price_ht_16' => string 'App\Entity\Donations' (length=20)
          'id_17' => string 'App\Entity\Donateurs' (length=20)
          'enterprise_18' => string 'App\Entity\Donateurs' (length=20)
          'social_address_19' => string 'App\Entity\Donateurs' (length=20)
          'siret_20' => string 'App\Entity\Donateurs' (length=20)
          'postal_adress_21' => string 'App\Entity\Donateurs' (length=20)
          'enterprise_type_22' => string 'App\Entity\Donateurs' (length=20)
          'dpt_23' => string 'App\Entity\Donateurs' (length=20)
          'product_24' => string 'App\Entity\Donateurs' (length=20)
          'product_type_25' => string 'App\Entity\Donateurs' (length=20)
          'contact_name_26' => string 'App\Entity\Donateurs' (length=20)
          'contact_function_27' => string 'App\Entity\Donateurs' (length=20)
          'phone_28' => string 'App\Entity\Donateurs' (length=20)
          'email_29' => string 'App\Entity\Donateurs' (length=20)
          'national_provider_30' => string 'App\Entity\Donateurs' (length=20)
          'prospector_adviser_31' => string 'App\Entity\Donateurs' (length=20)

Два объекта отображаются в правильных полях! Но теперь я не могу отправить на ветку, на мой взгляд, все пусто (без сообщения об ошибке).

Это сводит меня с ума уже 3 дня. Нужна помощь, пожалуйста, и извините за мой английский.

ОБНОВИТЬ Сущности.

Донатеры:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass = "App\Repository\DonateursRepository")
 */
class Donateurs
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

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

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $socialAddress;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $siret;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $postalAdress;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $enterprise_type;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $dpt;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $product;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $productType;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $contactName;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $contactFunction;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $phone;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $email;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $nationalProvider;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $prospectorAdviser;

    /**
     * @ORM\OneToMany(targetEntity = "App\Entity\Donations", mappedBy = "donateurs")
     */
    private $donations;

    public function __construct()
    {
        $this->donations = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEnterprise(): ?string
    {
        return $this->enterprise;
    }

    public function setEnterprise(string $enterprise): self
    {
        $this->enterprise = $enterprise;

        return $this;
    }

    public function getSocialAddress(): ?string
    {
        return $this->socialAddress;
    }

    public function setSocialAddress(?string $socialAddress): self
    {
        $this->socialAddress = $socialAddress;

        return $this;
    }

    public function getSiret(): ?int
    {
        return $this->siret;
    }

    public function setSiret(?int $siret): self
    {
        $this->siret = $siret;

        return $this;
    }

    public function getPostalAdress(): ?string
    {
        return $this->postalAdress;
    }

    public function setPostalAdress(?string $postalAdress): self
    {
        $this->postalAdress = $postalAdress;

        return $this;
    }

    public function getEnterpriseType(): ?string
    {
        return $this->enterprise_type;
    }

    public function setEnterpriseType(?string $enterprise_type): self
    {
        $this->enterprise_type = $enterprise_type;

        return $this;
    }

    public function getDpt(): ?int
    {
        return $this->dpt;
    }

    public function setDpt(?int $dpt): self
    {
        $this->dpt = $dpt;

        return $this;
    }

    public function getProduct(): ?string
    {
        return $this->product;
    }

    public function setProduct(?string $product): self
    {
        $this->product = $product;

        return $this;
    }

    public function getProductType(): ?string
    {
        return $this->productType;
    }

    public function setProductType(?string $productType): self
    {
        $this->productType = $productType;

        return $this;
    }

    public function getContactName(): ?string
    {
        return $this->contactName;
    }

    public function setContactName(?string $contactName): self
    {
        $this->contactName = $contactName;

        return $this;
    }

    public function getContactFunction(): ?string
    {
        return $this->contactFunction;
    }

    public function setContactFunction(?string $contactFunction): self
    {
        $this->contactFunction = $contactFunction;

        return $this;
    }

    public function getPhone(): ?string
    {
        return $this->phone;
    }

    public function setPhone(?string $phone): self
    {
        $this->phone = $phone;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(?string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getNationalProvider(): ?string
    {
        return $this->nationalProvider;
    }

    public function setNationalProvider(?string $nationalProvider): self
    {
        $this->nationalProvider = $nationalProvider;

        return $this;
    }

    public function getProspectorAdviser(): ?string
    {
        return $this->prospectorAdviser;
    }

    public function setProspectorAdviser(?string $prospectorAdviser): self
    {
        $this->prospectorAdviser = $prospectorAdviser;

        return $this;
    }
}

Пожертвования:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * @ORM\Entity(repositoryClass = "App\Repository\DonationsRepository")
 */
class Donations
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

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

    /**
     * @ORM\Column(type = "datetime", nullable=true)
     */
    private $departDate;

    /**
     * @ORM\Column(type = "datetime", nullable=true)
     */
    private $certifDate;

    /**
     * @ORM\Column(type = "string", length=50, nullable=true)
     */
    private $certifRef;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $productName;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $donorId;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $family;

    /**
     * @ORM\Column(type = "string", length=50, nullable=true)
     */
    private $recipient;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $carrierId;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $nbPallet;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $weight;

    /**
     * @ORM\Column(type = "datetime", nullable=true)
     */
    private $billDate;

    /**
     * @ORM\Column(type = "datetime", nullable=true)
     */
    private $billReceptionDate;

    /**
     * @ORM\Column(type = "datetime", nullable=true)
     */
    private $billSentValidationDate;

    /**
     * @ORM\Column(type = "string", length=80, nullable=true)
     */
    private $billReference;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $price_HT;

    /**
     * @ORM\ManyToOne(targetEntity = "App\Entity\Donateurs", inversedBy = "donations")
     */
    private $donateurs;

    public function __construct()
    {
        $this->donateurs = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getProductName(): ?string
    {
        return $this->productName;
    }

    public function setProductName(string $productName): self
    {
        $this->productName = $productName;

        return $this;
    }

    public function getNbPallet(): ?int
    {
        return $this->nbPallet;
    }

    public function setNbPallet(int $nbPallet): self
    {
        $this->nbPallet = $nbPallet;

        return $this;
    }

    public function getMovement(): ?string
    {
        return $this->movement;
    }

    public function setMovement(string $movement): self
    {
        $this->movement = $movement;

        return $this;
    }

    public function getDepartDate(): ?\DateTimeInterface
    {
        return $this->departDate;
    }

    public function setDepartDate(\DateTimeInterface $departDate): self
    {
        $this->departDate = $departDate;

        return $this;
    }

    public function getCertifDate(): ?\DateTimeInterface
    {
        return $this->certifDate;
    }

    public function setCertifDate(\DateTimeInterface $certifDate): self
    {
        $this->certifDate = $certifDate;

        return $this;
    }

    public function getCertifRef(): ?string
    {
        return $this->certifRef;
    }

    public function setCertifRef(?string $certifRef): self
    {
        $this->certifRef = $certifRef;

        return $this;
    }

    public function getFamily(): ?string
    {
        return $this->family;
    }

    public function setFamily(string $family): self
    {
        $this->family = $family;

        return $this;
    }

    public function setContactId(int $contactId): self
    {
        $this->contactId = $contactId;

        return $this;
    }

    public function getRecipient(): ?string
    {
        return $this->recipient;
    }

    public function setRecipient(string $recipient): self
    {
        $this->recipient = $recipient;

        return $this;
    }

    public function getCarrierId(): ?int
    {
        return $this->carrierId;
    }

    public function setCarrierId(int $carrierId): self
    {
        $this->carrierId = $carrierId;

        return $this;
    }

    public function getWeight(): ?int
    {
        return $this->weight;
    }

    public function setWeight(int $weight): self
    {
        $this->weight = $weight;

        return $this;
    }

    public function getBillDate(): ?\DateTimeInterface
    {
        return $this->billDate;
    }

    public function setBillDate(\DateTimeInterface $billDate): self
    {
        $this->billDate = $billDate;

        return $this;
    }

    public function getBillReceptionDate(): ?\DateTimeInterface
    {
        return $this->billReceptionDate;
    }

    public function setBillReceptionDate(\DateTimeInterface $billReceptionDate): self
    {
        $this->billReceptionDate = $billReceptionDate;

        return $this;
    }

    public function getBillSentValidationDate(): ?\DateTimeInterface
    {
        return $this->billSentValidationDate;
    }

    public function setBillSentValidationDate(?\DateTimeInterface $billSentValidationDate): self
    {
        $this->billSentValidationDate = $billSentValidationDate;

        return $this;
    }

    public function getBillReference(): ?string
    {
        return $this->billReference;
    }

    public function setBillReference(?string $billReference): self
    {
        $this->billReference = $billReference;

        return $this;
    }

    public function getPriceHT(): ?int
    {
        return $this->price_HT;
    }

    public function setPriceHT(?int $price_HT): self
    {
        $this->price_HT = $price_HT;

        return $this;
    }

    public function getDonorId(): ?int
    {
        return $this->donorId;
    }

    public function setDonorId(int $donorId): self
    {
        $this->donorId = $donorId;

        return $this;
    }

    public function getDonateurs(): ?Collection
    {
        return $this->donateurs;
    }

    public function setDonateurs(?Donateurs $donateurs): self
    {
        $this->donateurs = $donateurs;
        return $this;
    }
}

Я не думаю, что вам нужно приводить Donateurs. Они будут загружаться автоматически при необходимости. Вы пытались использовать $repo->findAll(); в контроллере и {% for donateur in donation.donateurs %} {{ donateur.name }} {% endfor %} с веткой?

Vyctorya 15.05.2019 11:27

Смарт, спасибо :). Но это не работает ... Я получаю сообщение об ошибке, когда пытаюсь это сделать (внутри {% для пожертвований в пожертвованиях %}, правильно?) Вот ошибка: «Ни свойство «доноры», ни один из методов " donateurs()", "getdonateurs()"/"isdonateurs()"/"hasdonateurs()" или "__call()" существуют и имеют публичный доступ в классе "App\Entity\Donations"

shaax 15.05.2019 11:37

Хорошо, у вас есть функция, чтобы получить донатеров в классе пожертвований? Как вы создали отношения? Размещение класса пожертвования было бы действительно полезно.

Vyctorya 15.05.2019 11:39

Можете ли вы показать нам сущность ваших пожертвований? что-то могло сломаться в нем

Julien Bourdic 15.05.2019 11:53

@Vyctorya, спасибо, обновилось, теперь можно видеть сущности.

shaax 15.05.2019 12:06

Добавьте это в раздел «Пожертвования»: public function getDonateurs(): ?Collection { return $this->donateurs; }

Vyctorya 15.05.2019 12:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
6
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам просто нужно добавить аксессоры к свойству donateurs

/**
 * @ORM\ManyToOne(targetEntity = "App\Entity\Donateurs", inversedBy = "donations")
 */
private $donateurs;

public function getDonateurs()
{
    return $this->donateurs;
}

public function setDonateurs($donateurs)
{
    $donateurs = $this->donateurs;

    return $this;
}

Это должно решить вашу проблему

Редактировать :

Вы также должны добавить геттер и сеттер для атрибута donations в сущность Donateur.

Другой способ решить вашу проблему для "showAll" - использовать методы репозитория доктрины:

// You should suffix any action of your controller with "Action"
public function donAction(DonationsRepository $repo, Request $request)
{
    $results = $repo->findAll(); //
    var_dump($results);

    // Then return to Twig
}

Вы получите доступ к donateurs в своей ветке, выполнив:

{{ donation.donateurs }}

Сохраняя свой метод, что произойдет, если вы попытаетесь форсировать гидратацию вашей ассоциации, выполнив в своем методе репозитория:

public function showAll()
{
    $results = $this->createQueryBuilder('dr')
        ->select('dr, dn')
        ->leftJoin('dr.donateurs','dn')
        ->getQuery()
        ->execute([], Query::HYDRATE_OBJECT);

    return $results;
}

Если это все еще не работает, вы уверены, что в вашей базе данных есть donateur_id в вашей donation строке и соответствующая строка в вашей donateur таблице?

Спасибо за ваш ответ. Да, это была ошибка, без геттера не может работать, мой плохой. Но это не решит мою проблему. Атрибут «доноры» по-прежнему пуст, когда я var_dump свой запрос, как в моем первом посте.

shaax 15.05.2019 13:12

Вы добавили геттер и сеттер в объект Donateur? Их тоже не было

Julien Bourdic 15.05.2019 14:30

Я запутался. Проблема заключалась в сеттере и геттере, как сказали вы с Викторией. Но после 3-х дней тестирования я случайно удалил данные донора_id. Так что без id это не сработает. Теперь все хорошо. Я не могу добавить +1 к вашему ответу (у меня репутация <15), но... Спасибо. В самом деле.

shaax 15.05.2019 14:44

Полезно знать :) Я отредактировал свой ответ до того, как увидел ваш комментарий. Я добавил несколько советов, чтобы помочь вам (комментарий и имена переменных). Кажется, вы все еще не понимаете некоторые понятия;)

Julien Bourdic 15.05.2019 14:47

Да, спасибо, я только что видел :). Из-за этой проблемы (и, конечно, из-за ВАС) я многое узнал об отношениях сущностей и философии Doctrine ORM. «Merci l'ami! A un de ces jours sur Lyon peut-être x)».

shaax 15.05.2019 17:04

Другие вопросы по теме