【问题标题】:symfony 4 - Semantical Error with relation ManyToManysymfony 4 - 与多对多关系的语义错误
【发布时间】:2020-07-01 18:11:09
【问题描述】:

我已经使用 Symfony 开始了一个项目,并且我是这个框架的初学者。我通常可以通过阅读论坛和文档来纠正所有错误,但在这种情况下,我无法理解错误。

我有一个 WorkingTime 实体与许多 ManyToMany 关系:

<?php

namespace App\Entity;

use App\Repository\WorkingTimeRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=WorkingTimeRepository::class)
 */
class WorkingTime
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity=User::class, inversedBy="workingTimes")
     */
    private $user;

    /**
     * @ORM\ManyToMany(targetEntity=Customer::class, inversedBy="workingTimes")
     */
    private $customer;

    /**
     * @ORM\ManyToMany(targetEntity=Work::class, inversedBy="workingTimes")
     */
    private $work;

    /**
     * @ORM\ManyToMany(targetEntity=WorkingPlaceRelation::class, inversedBy="workingTimes")
     */
    private $workingPlace;

    /**
     * @ORM\Column(type="datetime")
     */
    private $createdAt;

    /**
     * @ORM\Column(type="integer")
     */
    private $totalTime;

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

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

    public function __construct()
    {
        $this->user = new ArrayCollection();
        $this->customer = new ArrayCollection();
        $this->work = new ArrayCollection();
        $this->workingPlace = new ArrayCollection();
        $this->setCreatedAt(new \datetime);
    }

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

    /**
     * @return Collection|User[]
     */
    public function getUser(): Collection
    {
        return $this->user;
    }

    public function setUser(?User $user): self
    {
        $this->user = $user;

        return $this;
    }

    public function addUser(User $user): self
    {
        if (!$this->user->contains($user)) {
            $this->user[] = $user;
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->user->contains($user)) {
            $this->user->removeElement($user);
        }

        return $this;
    }

    /**
     * @return Collection|Customer[]
     */
    public function getCustomer(): Collection
    {
        return $this->customer;
    }

    public function addCustomer(Customer $customer): self
    {
        if (!$this->customer->contains($customer)) {
            $this->customer[] = $customer;
        }

        return $this;
    }

    public function removeCustomer(Customer $customer): self
    {
        if ($this->customer->contains($customer)) {
            $this->customer->removeElement($customer);
        }

        return $this;
    }

    /**
     * @return Collection|Work[]
     */
    public function getWork(): Collection
    {
        return $this->work;
    }

    public function addWork(Work $work): self
    {
        if (!$this->work->contains($work)) {
            $this->work[] = $work;
        }

        return $this;
    }

    public function removeWork(Work $work): self
    {
        if ($this->work->contains($work)) {
            $this->work->removeElement($work);
        }

        return $this;
    }

    /**
     * @return Collection|WorkingPlaceRelation[]
     */
    public function getWorkingPlace(): Collection
    {
        return $this->workingPlace;
    }

    public function addWorkingPlace(WorkingPlaceRelation $workingPlace): self
    {
        if (!$this->workingPlace->contains($workingPlace)) {
            $this->workingPlace[] = $workingPlace;
        }

        return $this;
    }

    public function removeWorkingPlace(WorkingPlaceRelation $workingPlace): self
    {
        if ($this->workingPlace->contains($workingPlace)) {
            $this->workingPlace->removeElement($workingPlace);
        }

        return $this;
    }

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

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    public function getTotalTime(): ?int
    {
        return $this->totalTime;
    }

    public function setTotalTime(?int $totalTime): self
    {
        $this->totalTime = $totalTime;

        return $this;
    }

    public function getKmPerso(): ?int
    {
        return $this->kmPerso;
    }

    public function setKmPerso(?int $kmPerso): self
    {
        $this->kmPerso = $kmPerso;

        return $this;
    }

    public function getMeal(): ?int
    {
        return $this->meal;
    }

    public function setMeal(?int $meal): self
    {
        $this->meal = $meal;

        return $this;
    }
}

我想在这个实体的存储库中创建一个自定义查询:

public function findByDate($date)
{
    return $this->createQueryBuilder('w')
        ->where('w.createdAt = :date')
        ->setParameter('date', $date)
        ->orderBy('w.customer.firstname', 'ASC')
        ->setMaxResults(10)
        ->getQuery()
        ->getResult()
    ;
}

但我收到以下错误:

[语义错误] 第 0 行,第 85 列靠近“名称 ASC”:错误:类 App\Entity\WorkingTime 没有名为的字段或关联 客户名

你可以看到我的客户实体:

<?php

namespace App\Entity;

use App\Entity\Work;
use App\Repository\CustomerRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\Unique;

/**
 * @ORM\Entity(repositoryClass=CustomerRepository::class)
 */
class Customer
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Regex(
     * pattern = "/^[0-9]{5}$/",
     * message = "Le numéro de client ne peut être qu'un chiffre")
     */
    private $customer_number;

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

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

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

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

    /**
     * @ORM\Column(type="integer")
     * @Assert\Regex(
     * pattern = "/^[0-9]{4}$/",
     * message = "Le code postal doit contenir 4 chiffres")
     */
    private $zip_code;

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

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

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

    /**
     * @ORM\Column(type="datetime")
     */
    private $created_at;

    /**
     * @ORM\Column(type="datetime")
     */
    private $updated_at;

    /**
     * @ORM\Column(type="smallint")
     */
    private $active;

    /**
     * @ORM\OneToMany(targetEntity=Work::class, mappedBy="customer", orphanRemoval=true)
     */
    private $works;

    /**
     * @ORM\ManyToMany(targetEntity=WorkingTime::class, mappedBy="customer")
     */
    private $workingTimes;


    public function __construct()
    {
        $this->works = new ArrayCollection();
        $this->setActive(1);
        $this->setCreatedAt(new \DateTime());
        $this->setUpdatedAt(new \DateTime());
        $this->workingTimes = new ArrayCollection();
    }

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

    public function getCustomerNumber(): ?string
    {
        return $this->customer_number;
    }

    public function setCustomerNumber(?string $customer_number): self
    {
        $this->customer_number = $customer_number;

        return $this;
    }

    public function getCompagnyName(): ?string
    {
        return $this->compagny_name;
    }

    public function setCompagnyName(?string $compagny_name): self
    {
        $this->compagny_name = $compagny_name;

        return $this;
    }

    public function getFirstname(): ?string
    {
        return $this->firstname;
    }

    public function setFirstname(?string $firstname): self
    {
        $this->firstname = $firstname;

        return $this;
    }

    public function getLastname(): ?string
    {
        return $this->lastname;
    }

    public function setLastname(?string $lastname): self
    {
        $this->lastname = $lastname;

        return $this;
    }

    public function getStreet(): ?string
    {
        return $this->street;
    }

    public function setStreet(?string $street): self
    {
        $this->street = $street;

        return $this;
    }

    public function getZipCode(): ?int
    {
        return $this->zip_code;
    }

    public function setZipCode(?int $zip_code): self
    {
        $this->zip_code = $zip_code;

        return $this;
    }

    public function getCity(): ?string
    {
        return $this->city;
    }

    public function setCity(?string $city): self
    {
        $this->city = $city;

        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 getCreatedAt(): ?\DateTimeInterface
    {
        return $this->created_at;
    }

    public function setCreatedAt(\DateTimeInterface $created_at): self
    {
        $this->created_at = $created_at;

        return $this;
    }

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

    public function setUpdatedAt(\DateTimeInterface $updated_at): self
    {
        $this->updated_at = $updated_at;

        return $this;
    }

    public function getActive(): ?int
    {
        return $this->active;
    }

    public function setActive(int $active): self
    {
        $this->active = $active;

        return $this;
    }

    /**
     * @return Collection|Work[]
     */
    public function getWorks(): Collection
    {
        return $this->works;
    }

    public function addWork(Work $work): self
    {
        if (!$this->works->contains($work)) {
            $this->works[] = $work;
            $work->setCustomer($this);
        }

        return $this;
    }

    public function removeWork(Work $work): self
    {
        if ($this->works->contains($work)) {
            $this->works->removeElement($work);
            // set the owning side to null (unless already changed)
            if ($work->getCustomer() === $this) {
                $work->setCustomer(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|WorkingTime[]
     */
    public function getWorkingTimes(): Collection
    {
        return $this->workingTimes;
    }

    public function addWorkingTime(WorkingTime $workingTime): self
    {
        if (!$this->workingTimes->contains($workingTime)) {
            $this->workingTimes[] = $workingTime;
            $workingTime->addCustomer($this);
        }

        return $this;
    }

    public function removeWorkingTime(WorkingTime $workingTime): self
    {
        if ($this->workingTimes->contains($workingTime)) {
            $this->workingTimes->removeElement($workingTime);
            $workingTime->removeCustomer($this);
        }

        return $this;
    }

}

【问题讨论】:

  • 客户是一个实体(甚至是多个实体)。您不能按实体订购。选择该实体或某事的字段
  • 感谢您的回复@Jakumi 我已经用 ->orderBy('w.customer.firstname', 'ASC') 进行了测试,但我已经有一个错误
  • 嗯,不会是同样的错误,请更新您的问题(追加),以便我们跟踪代码更改和发生的新错误。
  • 在上面的代码中,一个WorkingTime可以有很多Customers,一个Customer可以有很多WorkingTimes。您的 Doctrine 查询将返回一个工作时间数组,这些工作时间是在指定日期创建的,最多有 10 个结果。你到底想通过什么来订购这些?如果每个 WorkingTime 都有很多客户,那么尝试按客户名称对 WorkingTime 数组进行排序没有多大意义。您是否真的希望 WorkingTime 的客户按名称的字母顺序排列,而不是 WorkingTime 本身?
  • 与问题无关,但由于WorkingTime和Customer之间的关系是ManyToMany,你的WorkingTime属性应该是$customers的复数形式

标签: php symfony doctrine doctrine-odm


【解决方案1】:

您需要像这样加入客户:

public function findByDate($date)
{
    return $this->createQueryBuilder('w')
        ->join('w.customer', 'u')
        ->where('w.createdAt = :date')
        ->setParameter('date', $date)
        ->orderBy('u.firstname', 'ASC')
        ->setMaxResults(10)
        ->getQuery()
        ->getResult()
        ;
}

【讨论】:

  • 谢谢@Rawburner
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2018-03-04
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多