在我的Symfony项目中,我有一个“ExerciceComptable”和一个“DocumentAttendu”实体。在ExerciceComptable中有一个引用DocumentAttendu(OneToMany)的关系。在DocumentAttendu中,我有一个名为“recu”的属性,它是一个布尔值。
我需要检索所有已完成的“ExerciceComptable”,这意味着“ExerciceComptable”的所有“DocumentAttendu”都将属性“recu”设置为true。
我怎样才能做到呢?
可执行
#[ORM\OneToMany(mappedBy: 'exercice', targetEntity: DocumentAttendu::class)]
private Collection $documentAttendus;
/**
* @return Collection<int, DocumentAttendu>
*/
public function getDocumentAttendus(): Collection
{
return $this->documentAttendus;
}
public function addDocumentAttendu(DocumentAttendu $documentAttendu): self
{
if (!$this->documentAttendus->contains($documentAttendu)) {
$this->documentAttendus->add($documentAttendu);
$documentAttendu->setExercice($this);
}
return $this;
}
public function removeDocumentAttendu(DocumentAttendu $documentAttendu): self
{
if ($this->documentAttendus->removeElement($documentAttendu)) {
if ($documentAttendu->getExercice() === $this) {
$documentAttendu->setExercice(null);
}
}
return $this;
}
文件出席人
#[ORM\ManyToOne(inversedBy: 'documentAttendus')]
#[ORM\JoinColumn(nullable: false)]
private ?ExerciceComptable $exercice = null;
#[ORM\Column(nullable: true)]
private ?bool $recu = null;
public function getExercice(): ?ExerciceComptable
{
return $this->exercice;
}
public function setExercice(?ExerciceComptable $exercice): self
{
$this->exercice = $exercice;
return $this;
}
public function isRecu(): ?bool
{
return $this->recu;
}
public function setRecu(?bool $recu): self
{
$this->recu = $recu;
return $this;
}
"我所尝试的"
$qb = $this->createQueryBuilder( 'ec' );
$qb->join( 'ec.documentAttendus', 'da');
$qb->andWhere('da.recu = true');
如果只有一个“DocumentAttendu”具有“recu”= true,则查询将找到它。我需要所有“DocumentAttendu”具有“recu”= true,而不是仅五个中的一个。
我也尝试过使用Criteria,但我不太明白它是怎么工作的。我尝试过一些行,比如“having('COUNT ')"等等...但我不确定我是否正确地使用了它。
重要的一点,我需要在“ExerciceComptableRepository”中。
2条答案
按热度按时间omtl5h9j1#
最简单的解决方案可能是子查询。更具体地说,使用来自doctrine的Expr类。使用“where not exists (subquery)“,应该会给予出正确的结果。
你会得到这样的结果:
简而言之:您将获取所有不具有
DocumentAttendu
实体的ExerciceComptable
实体,其中recu = false
**注意:**如果
ExerciceComptable
实体没有任何documentAttendus
,此查询也将返回该ExerciceComptable
实体mrfwxfqh2#
我的解决方案不是一个完整的理论解决方案,可能会导致更大数据的性能问题,但我相信它可能是处理此类非常具体的情况的一个很好的方法。
让我们来谈谈正确的Sql查询之前的学说,它应该是这样的:
则仅检索文档总数=已接收文档的
ExerciceComptable
。需要注意的是select内部的子查询对性能不好,因为它对每个结果只执行一个查询(所以如果你有100个
ExerciceComptable
,它将执行100个子查询),而使用join的子查询对整个查询只执行一个查询。问题是你不会在仓库中得到带有原始mysql函数的实体对象,所以你有两个选择。
findBy(['id' => $arrayOfIds])
-〉您得到了要查找的对象。这是个骗局,是真的。
但我相信特定的用例和教条往往很难维护。其中sql查询可以很容易地测试和更改。
事实上,只有第一个查询需要维护,第二个查询总是非常快,因为对id的查询非常快。
如果您想查看DQL与子查询的案例,请查看:Join subquery with doctrine 2 DBAL
我给了你一般性的指导方针,我希望它能有所帮助。
**永远不要忘记:**永远不要在select或where中执行子查询。它的性能非常差,因为它在服务器端为每一行结果执行一个子查询。请使用内/左连接来执行此操作