Doctrine2离开加入所有加入尊重条件的地方

时间:2017-04-25 14:04:14

标签: doctrine-orm

我正面临着一个关于学说请求的问题。我正在使用queryBuilder但无法找到如何正确处理我的请求。

我的数据库架构是这样的:我在两个实体之间有一个ManyToMany关系:" Lot"和"保释"。

我想要做的是获取与一个" Lot"相关的数据。如果所有的"保释"遵循以下两条规则之一:

  1. 删除保释(其字段deleteDate不为空)
  2. 我设置为参数的日期不在Bail的startDate和endDate之间(Bail太旧或最近)
  3. 我希望只有当所有保释都遵循两条规则中的一条时才能得到Lot,这意味着如果一个保释未被删除或太旧/最近,我就不会获得该地段。

    我已经在条件上找了几个关于leftJoin的主题,但似乎无法使它工作。

    这是我到目前为止所做的:

    $queryBuilder = $this->createQueryBuilder('lot');
        $queryBuilder
            ->select(
                'typo.id as typologyId',
                'typo.label as typology',
                'lot.floor',
                'sum(lot.sdp) as surface',
                'sum(1) as total'
            )
            ->leftJoin('lot.typology', 'typo')
            ->leftJoin('lot.batiment', 'batiment')
            ->leftJoin('lot.baux', 'bail', 'WITH', ':date not between bail.datePriseEffet and bail.dateFin or bail.deleteDate is not null')
            ->leftJoin('batiment.building', 'building')
            ->andWhere('building.id = :buildingId')
            ->addOrderBy('typo.label')
            ->addOrderBy('lot.floor')
            ->groupBy('typologyId, typology, lot.floor')
            ->setParameters(array(":buildingId" =>$buildingId, ":date" =>$date));
    

    这不起作用,我得到了#34; Lot"如果其Bail中至少有一个被删除或太旧/最近,而不是全部。

    我该如何解决?

    也许我可以使用$ queryBuilder-> expr() - > exists()函数,但我真的不明白它是如何工作的。

1 个答案:

答案 0 :(得分:0)

一个(非常)迟到的答案!

假设您有一个与图书实体相关的图书馆实体:图书< = ManyToOne =>图书馆。现在让我们说一本书有一个属性$available。 如果您想要获取 ALL 书籍可用的所有库,此查询将 NOT 工作:

LibraryRepository
//....
$qb = $this->createQueryBuilder('l')
    -> leftJoin('l.books', 'b')
    -> andWhere("b.available = 1");

这将返回包含至少可用图书的库。

要获得预期结果,您必须构建两个查询: 第一个查询($ qb)将获取我们想要的实体(至少有一本书的库。

            $qb = $this->createQueryBuilder('lib') // We're selecting libraries but using a different alias because 'l' is already used in the other query
                ->join('lib.books', 'bo')
                ->andWhere("bo.available = 0");

第二个查询$ qb2将选择所有不属于第一个查询结果的库(因此可以使用所有书籍的库。

$qb2 = $this->createQueryBuilder('l');
$qb2 ->andWhere($qb->expr()->notIn('l.id', $qb->getDQL()));

注意有一个参数技巧:如果你必须在你的fisrt查询中使用一个参数,你必须在第二个查询中定义它(setParameter()方法)。