教义2与表格的差异是一对一的相同关系

时间:2018-04-10 06:27:22

标签: php doctrine-orm orm

我有2个具有相同的一对一关系的实体:

class FirstEntity {

...

 /**
  * @var \App\Entity\ThirdEntity
  *
  * @ORM\OneToOne(targetEntity="App\Entity\ThirdEntity")
  */
 protected $thirdEntity;



class SecondEntity {

...

 /**
  * @var \App\Entity\ThirdEntity
  *
  * @ORM\OneToOne(targetEntity="App\Entity\ThirdEntity")
  */
 protected $thirdEntity;

$thirdEntity字段无效。 有没有办法通过查询构建器或本机查询返回结果,如array_diff()opertion:

$firsts = array_map(function (FirstEntity $firstEntity) {
return $firstEntity->getThirdEntity()->getId();
}, $this->em->getRepository(FirstEntity::class)->findAll());

$seconds = array_map(function (SecondEntity $secondEntity) {
return $secondEntity->getThirdEntity()->getId();
}, $this->em->getRepository(SecondEntity::class)->findAll());

return array_diff($firsts, $seconds);

所以我想要的是与ThirdEntity但不与FirstEntity相关联的所有SecondEntity的列表。

1 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是使用本机查询或查询构建器(或多个本机查询/查询buidler)。这样,数据库将为您完成所有过滤,这意味着Doctrine不需要做太多工作。

查询构建器是最简单的方法,但确实要求您也从ThirdEntity映射到FirstEntitySecondEntity - 以下代码假定您已准备好映射。

$qb = $em->createQueryBuilder();
$result = $qb->select('t')->from('ThirdEntity', 't')
    ->innerJoin('t.firstEntity', 'f')
    ->leftJoin('t.secondEntity', 's')
    ->where($qb->expr()->isNull('s.id'));
    ->getQuery()->getResult();

这里发生的事情是,我们要求数据库将所有ThirdEntity条记录inner join与所有FirstEntity条记录一起使用(所以ThirdEntity没有FirstEntity }将不包括在内)。然后我们left join使用SecondEntity,这意味着如果ThirdEntity也与SecondEntity相关联,则其数据可用于过滤,否则我们会获得NULL对于所有SecondEntity列。最后一步是仅选择那些没有SecondEntity的记录(意思是其ID为null)。

取决于确切的数据集,这种“一个查询”方法可能无法为您提供最佳性能。 可以更快地首先选择与ThirdEntity有关系的所有FirstEntity项的ID然后(在单独的查询中,您使用该ID列表作为参数)过滤掉那些与SecondEntity有关系的项目。反过来做这两件事也可能更快。我不是没想到的,所以我们会把它留给另一个问题(或者这个问题的另一个答案)。