【问题标题】:Doctrine leftJoin entity is not a child of the main entity学说 leftJoin 实体不是主实体的子实体
【发布时间】: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 旁边。所以,我们有两个问题:

  1. payment 是一个对象,而不是一个数组。
  2. 它有一个自己的条目,但它应该出现在结果集中的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


【解决方案1】:

您是否尝试过将 QueryBuilder 辅助方法 addSelect 与 leftJoin 一起使用。

就我个人而言,我以前从未使用过它,但我知道它存在并且它对您 IMO 很有用。

一些文档是here,here 是一些 Doctrine 教程。

【讨论】:

  • 好的,它对我有什么帮助?
  • 如果我理解得很好,它会将您的选择(加入)添加到现有的查询选择中,并且数组水合物应该看起来与您预期的相似。
  • 嗯,这与我已经做过的基本相同。当您在 QueryBuilder 上使用带有数组作为参数的 select 方法时,它会准确地选择您在数组中指定的那些字段。据我所知,QueryBuilder 方法总是返回自身的实例。所以,正如你所说的“现有查询”。
  • 在你的例子中,你有 $builder->select(['sapExport.id']);结果是 {...} [0] => {}。尝试使用 addSelec 而不是仅选择。如果您对 sapExport 有正确的左连接 - 它应该作为结果 {.... [sapExport} => {} } 起作用。 ?
  • 我想你误解了我的意思。我编辑了我的问题。请看一下(如果我错了,请告诉我)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
相关资源
最近更新 更多