【发布时间】:2018-08-08 03:09:07
【问题描述】:
我有很多 leftJoin 的巨大查询。除了一个之外,所有 leftJoin 都在实体中关联。如果我使用数组水合模式,则不会每次都有自己的条目。
基本上,我使用的是 Shopware,此查询是插件的一部分。但是,除了我自己的以外,每个引用的实体都可以在 Shopware GitHub 存储库中找到:https://github.com/shopware/shopware/blob/5.3/engine/Shopware/Models/Order/Order.php
我在存储库中的查询:
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select([
'orders',
'details',
'payment.id',
'payment.name',
'payment.description',
'payment.action',
'payment.pluginId',
'paymentInstances',
'shipping',
'billing',
'billingCountry',
'shippingCountry',
'paymentPayPal',
'paymentStatus',
]);
$builder->from('Shopware\Models\Order\Order', 'orders');
$builder->leftJoin('orders.details', 'details')
->leftJoin('orders.payment', 'payment')
->leftJoin('orders.paymentInstances', 'paymentInstances')
->leftJoin('SapExport\Models\PaymentPayPal', 'paymentPayPal', \Doctrine\ORM\Query\Expr\Join::WITH, 'orders.number = paymentPayPal.ordernumber AND payment.name = \'paypal\'')
->leftJoin('orders.billing', 'billing')
->leftJoin('billing.country', 'billingCountry')
->leftJoin('orders.shipping', 'shipping')
->leftJoin('shipping.country', 'shippingCountry')
->leftJoin('orders.paymentStatus', 'paymentStatus');
$builder->where('orders.cleared = ' . Status::PAYMENT_STATE_COMPLETELY_PAID)
->andWhere($builder->expr()->notIn('orders.id', $this->getSapExportIdsQuery()->getDQL()));
$builder->orderBy('orders.id', 'DESC');
where 子句中的子选择查询:
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select([
'sapExport.id'
]);
$builder->from('SapExport\Models\SapExport', 'sapExport');
如果我将它水合为数组,它会输出类似这样的内容(json 编码数据):
[
[
{
"id": 10353,
"number": "650004023",
"customerId": 4235,
"status": 0,
"cleared": 12,
"paymentId": 7,
"dispatchId": 10,
"partnerId": "",
"shopId": 1,
"invoiceAmount": 99.95,
"invoiceAmountNet": 83.99,
"invoiceShipping": 0,
"invoiceShippingNet": 0,
...
"details": [
{
...
}
],
"paymentInstances": [
{
...
}
],
"billing": {
...
},
"shipping": {
...
},
"paymentStatus": {
...
}
}
],
{
"0": {
"id": 251,
"ordernumber": "650004023",
"referenceNumber": "34TEST",
"instructionType": "TEST",
"bankName": "bank name",
"accountHolder": "PayPal Europe",
"iban": "DEXXXXXX",
"amountValue": "99.95",
"amountCurrency": "EUR",
"paymentDueDate": {
"date": "2018-01-31 00:00:00.000000",
"timezone_type": 3,
"timezone": "Europe\/Berlin"
},
"links": "[{\"href\":\"https://www.example.com\",\"rel\":\"self\",\"method\":\"GET\"}]"
},
"id": 7,
"name": "paypal",
"description": "PayPal",
"action": "payment_paypal",
"pluginId": 64
}
]
需要的结果/预期的结果:
[
[
{
"id": 10353,
"number": "650004023",
"customerId": 4235,
"status": 0,
"cleared": 12,
"paymentId": 7,
"dispatchId": 10,
"partnerId": "",
"shopId": 1,
"invoiceAmount": 99.95,
"invoiceAmountNet": 83.99,
"invoiceShipping": 0,
"invoiceShippingNet": 0,
...
"details": [
{
...
}
],
"paymentInstances": [
{
...
}
],
"billing": {
...
},
"shipping": {
...
},
"paymentStatus": {
...
},
"paymentPayPal": {
"id": 251,
"ordernumber": "650004023",
"referenceNumber": "34TEST",
"instructionType": "TEST",
"bankName": "bank name",
"accountHolder": "PayPal Europe",
"iban": "DEXXXXXX",
"amountValue": "99.95",
"amountCurrency": "EUR",
"paymentDueDate": {
"date": "2018-01-31 00:00:00.000000",
"timezone_type": 3,
"timezone": "Europe\/Berlin"
},
"links": "[{\"href\":\"https://www.example.com\",\"rel\":\"self\",\"method\":\"GET\"}]"
},
"payment": {
"id": 7,
"name": "paypal",
"description": "PayPal",
"action": "payment_paypal",
"pluginId": 64
}
}
]
]
如果我在数据库上执行 SQL,结果集是预期的。所以,这似乎是一个奇怪的学说实体映射。
编辑:为了解决我的实际问题,我有:实体payment不在主实体上,称为orders。它得到一个自己的对象,就在数组结果集中的orders 旁边。所以,我们有两个问题:
-
payment是一个对象,而不是一个数组。 - 它有一个自己的条目,但它应该出现在结果集中的
orders条目下。
另外,paymentPayPal 实体完全没有出现在结果集中。 但它应该,因为我也选择了它。
编辑 2:这是生成的 DQL 查询(请注意,我稍微减少了 details 实体,因为我不需要它的所有列) :
选择订单、details.id、details.articleId、details.number、 details.articleNumber, details.price, details.quantity, details.articleName, details.mode, details.esdArticle, details.unit, details.packUnit,payment.id,payment.name,payment.description, payment.action, payment.pluginId, paymentInstances, shipping, billing, billingCountry, shippingCountry, paymentPayPal, paymentStatus FROM Shopware\Models\Order\Order orders LEFT JOIN orders.details 详情 LEFT JOIN orders.payment 支付 LEFT JOIN orders.paymentInstances paymentInstances 左加入 SapExport\Models\PaymentPayPal paymentPayPal WITH orders.number = paymentPayPal.ordernumber AND payment.name = 'paypal' 左加入 orders.billing billing 左加入 billing.country billingCountry LEFT 加入 orders.shipping 运输 LEFT 加入 shipping.country shippingCountry 左加入 orders.paymentStatus paymentStatus WHERE orders.cleared = 12 AND orders.id NOT IN(SELECT sapExport.id 来自 SapExport\Models\SapExport sapExport) ORDER BY orders.id DESC
编辑 3:查询工作正常,如果我不离开加入贝宝表。如果客户选择贝宝作为他的订单的付款类型,我需要这张表来获取更多信息。但只有对于这种类型,我才需要那些额外的信息。据我所知,leftJoin 应该可以解决问题。因为,如果它不是贝宝,它应该加入一个带有nulled 列的空记录集。但我想知道为什么 Doctrine 会这样,SQL Query 挂件效果很好......
【问题讨论】:
-
如果您使用具有适当关系设置的实体,那么为什么不使用 getter 和 setter 来检索您需要的数据呢?让教义承担重任。例如:
Order::getDetails。如果您需要大量信息,请创建一个toArray方法并转储您需要的信息。 -
@NishitManjarawala 是的,每个 sql 聚合函数都需要一个 group by 语句。但我的查询中没有这个。但是,我通过添加
group by orders.id进行了尝试。不会改变任何东西。 @DevDonkey 我没有正确设置实体,因为我无法更改 Shopware 的核心模型。这就是为什么我需要如此复杂的查询。好吧,我可以更改 Shopware 的核心模型,但每次更新后它都会消失。
标签: php doctrine-orm left-join doctrine-query