【问题标题】:How to access an attribute of a LEFT JOIN on a ManyToMany relation?如何访问多对多关系上的左连接属性?
【发布时间】:2017-01-05 15:05:33
【问题描述】:

我有三个与各种关系相关联的实体:

-Band-
name
...
tours (ManyToMany with Tour)
shows (OneToMany with Show)

-Tour-
name
...
bands (ManyToMany with Band)
$shows(OneToMany with Show)

-Show-
date
...
band(ManyToOne with Band, nullable)
tour(ManyToOne with Tour, nullable)

我可以为 Band 设置 Show(然后 show_tour 为 NULL),也可以为 Tour 设置 Show(然后 show_band 为 NULL)。

现在,我想获取给定Band 的所有Show。我的 DQL 是这样的:

public function findAllShowsToComeFor($band)
{
    $date = new \DateTime('now');
    return $this->createQueryBuilder('s')
        ->leftJoin('s.band', 'band')
        ->where('band.id = :bid')
        ->setParameter('bid', $band->getId())
        ->leftJoin('s.tour', 'tour')
        ->where('tour.bands = :tid')
        ->setParameter('tid', $band->getId())
        ->andWhere('s.day >= :date')
        ->setParameter('date', $date->format('Y-m-d'))
        ->orderBy('s.day', 'ASC')
        ->getQuery()
        ->getResult();
}

当然,这会引发语法错误([Semantical Error] line 0, col 92 near 'bands = :tid': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.),因为这些行:

->leftJoin('s.tour', 'tour')
->where('tour.bands = :tid')
->setParameter('tid', $band->getId())

我需要做类似的事情:

->leftJoin('s.tour', 'tour')
->where('tour.bands.id IN :tid')
->setParameter('tid', $band->getId())

但这是不可能的……

谁能帮忙?

【问题讨论】:

    标签: symfony doctrine-orm dql


    【解决方案1】:

    MEMBER OF,相信你也想要这样的:

    $this->createQueryBuilder('s')
            ->leftJoin('s.tour', 'tour')
            ->where('s.band = :band OR :band MEMBER OF tour.bands')
            ->setParameter('band', $band)
            ->andWhere('s.day >= :date')
            ->setParameter('date', $date->format('Y-m-d'))
            ->orderBy('s.day', 'ASC')
            ->getQuery()
            ->getResult();
    

    【讨论】:

    • 工作得很好!谢谢!
    【解决方案2】:

    如果您已经在 Band 上完成了 Tour,则无需过滤 Band ID。

    所以这会给你这个:

    $this->createQueryBuilder('s')
        ->join('s.band', 'band')
        ->where('band.id = :bid')
        ->leftJoin('s.tour', 'tour')
        ->where('s.day >= :date')
        ->orderBy('s.day', 'ASC')
        ->setParameter('date', $date->format('Y-m-d'))
        ->setParameter('bid', $band->getId())
        ->getQuery()
        ->getResult();
    

    有了这个,你会得到一个 Show 的 ArrayCollection,如果你对它执行 ->getTour,你可能会有一个 Tour(或 NULL)。

    【讨论】:

    • 您可以从 leftJoin 访问属性,这里的问题是 tours.bands.id :您没有加入 Tour 和 Band。
    • 这个查询没有给我任何结果... "SELECT s0_.id AS id_0, s0_.day AS day_1, s0_.country AS country_2, s0_.city AS city_3, s0_.venue AS场地_4,s0_.band_id AS band_id_5,s0_.tour_id AS tour_id_6 FROM show s0_ INNER JOIN band b1_ ON s0_.band_id = b1_.id LEFT JOIN tour t2_ ON s0_.tour_id = t2_.id WHERE b1_.id = 1 AND s0_ .day >= '2017-01-05' ORDER BY s0_.day ASC;"
    猜你喜欢
    • 1970-01-01
    • 2013-12-28
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多