Symfony & Doctrine InnerJoin

Posted

技术标签:

【中文标题】Symfony & Doctrine InnerJoin【英文标题】: 【发布时间】:2016-07-18 19:32:32 【问题描述】:

我正在尝试与学说查询生成器进行联接。

$query = $this->createQueryBuilder('od');
$query->innerJoin(Order::class, 'o', Expr\Join::WITH, 'o.orderid = od.orderid');
$query->where('o.userid = :userid')
$query->andWhere('od.orderstatusid IN (:orderstatusid)')
$query->setParameter('userid', $userid);
$query->setParameter('orderstatusid', array(5, 6, 7, 8, 10))

请求失败,因为生成的 SQL 是:

SELECT od FROM OrderDetail od INNER JOIN Order o WITH o.orderid = od.orderid WHERE o.userid = :userid AND od.orderstatusid IN (:orderstatusid)

或者应该是

SELECT od FROM OrderDetail od INNER JOIN Order o ON o.orderid = od.orderid WHERE o.userid = :userid AND od.orderstatusid IN (:orderstatusid)

我不能使用 $query->innerJoin(Order::class, 'o', Expr\Join::ON, 'o.orderid = od.orderid');因为我收到了这个错误:

[Syntax Error] line 0, col 91: Error: Expected Doctrine\\ORM\\Query\\Lexer::T_WITH, got 'ON'

如果我不使用连接条件,则学说不会从模型中得到它,所以我没有好的结果。

如何使用 querybuilder 进行连接和位置?

感谢您的帮助

编辑: 这是模型:

OrderDetail:
    type: entity
    table: order_detail
    repositoryClass: OrderDetailRepository
    id:
        orderdetailid:
            type: integer
            nullable: false
            options:
                unsigned: false
            id: true
    fields:
        ...
    lifecycleCallbacks:   
    manyToOne:
        order:
            targetEntity: Order
            inversedBy: orderdetails
            joinColumn:
                name: orderid
                referencedColumnName: orderid


Order:
    type: entity
    table: order
    id:
        orderid:
            type: integer
            nullable: false
            options:
                unsigned: false
            id: true
    fields:

    lifecycleCallbacks:   
    oneToMany:
        orderdetails:
            targetEntity: OrderDetail
            mappedBy: order
            fetch: EAGER

【问题讨论】:

你在做什么看起来不错。 WITH是DQL,不是SQL,你确定那是实际生成的SQL吗?另外,请同时发布您的实体关系。 我用我的模型编辑 【参考方案1】:

检查完您的实体后,我认为您的查询可以简化一点。您实际上根本不需要 WITH。

    $result = $this->createQueryBuilder('od')
        ->join('od.order', 'o')
        ->addSelect('o')
        ->where('o.userid = :userid')
        ->andWhere('od.orderstatusid IN (:orderstatusid)')
        ->setParameter('userid', $userid)
        ->setParameter('orderstatusid', array(5, 6, 7, 8, 10))
        ->getQuery()->getResult()
    ;

Doctrine 足够聪明,知道 od.order 表示 OrderDetail -> Order 关系并为您管理该连接。只有当您有一些非常具体的查询要求时,您才真正需要使用 WITH。

【讨论】:

【参考方案2】:

在Doctrine 文档中对此进行解释:

$qb->innerJoin('u.Group', 'g', Expr\Join::WITH, $qb->expr()->eq('u.status_id', '?1'));

$qb->innerJoin('u.Group', 'g', 'WITH', 'u.status = ?1');

$qb->innerJoin('u.Group', 'g', 'WITH', 'u.status = ?1', 'g.id');

我推荐使用这种方式:

$query->innerJoin('od.Order', 'o', 'WITH', 'od.orderstatusid IN (:orderstatusid)');

这种方式查询是最优化的,不需要使用“o.orderid = od.orderid”和“$query->andWhere('od.orderstatusid IN (:orderstatusid)')”。

【讨论】:

如果我用的话,join不好,我要指定join keys orderid

以上是关于Symfony & Doctrine InnerJoin的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine DQL (Symfony2) - WHERE 连接字段是 IN params

Symfony & Doctrine InnerJoin

Symfony2/Doctrine 提交表单需要很长时间

在 symfony 中查找当前 Doctrine 数据库连接设置

如何使用doctrine查询symfony2中实体类中的另一个实体

Symfony 5(Doctrine 2.9),Doctrine 不会为 ManyToOne 自引用关系生成迁移