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 数据库连接设置