我正在尝试使用Doctrine2将我的PHP应用程序移植到Zend Framework。这是一个网上商店平台。我需要编写一个带有额外条件的DQL查询来从用户购物车中的产品中选择附件。
我有一个传统的查询:
SELECT
...
FROM
product
INNER JOIN
accessory_to_product ON(product.productid = accessory_to_product.accessoryid AND accessory_to_product.productid IN(000,000,000))
但这必须是主义。我有以下实体:
<?php
/**
* @ORM\Table(name="product")
* @ORM\Entity(repositoryClass="BestBuy\Entity\Repository\ProductRepository")
*/
class Product extends \BasicEntity
{
/**
*
* @var integer
* @ORM\Column(type="integer",nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $productid;
/**
*
* @var string
* @ORM\Column(type="string",nullable=false)
*/
protected $title;
/**
*
* @var string
* @ORM\Column(type="text",nullable=false)
*/
protected $description;
/**
*
* @var string
* @ORM\Column(type="datetime",nullable=false)
*/
protected $insertdate;
//....
/**
*
* @var array
*
* @ORM\ManyToMany(targetEntity="Product")
* @ORM\JoinTable(name="accessory_to_product",
* joinColumns={@ORM\JoinColumn(name="accessoryid", referencedColumnName="productid")},
* inverseJoinColumns={@ORM\JoinColumn(name="accessoryid", referencedColumnName="productid", unique=false)});
*/
protected $accessories;
}
因此我想将此查询重写为Doctrine2:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('p')
->from('BestBuy\Entity\Product', 'p')
->join('p.accessories', 'a', Expr\Join::WITH, $qb->expr()->in('p.productid', ':products'))
->setParameter('products', $products);
但是这给了我以下查询:
SELECT
p0_.productid AS productid0,
p0_.title AS title1,
p0_.description AS description2,
p0_.insertdate AS insertdate3,
p0_.price AS price4,
p0_.model AS model5,
p0_.categoryid AS categoryid6,
p0_.deliverytimeid AS deliverytimeid7,
p0_.status AS status8,
p0_.weight AS weight9,
p0_.pagetitle AS pagetitle10,
p0_.metadescription AS metadescription11,
p0_.youtubecode AS youtubecode12
FROM
product p0_
INNER JOIN
accessory_to_product a2_ ON p0_.productid = a2_.accessoryid
INNER JOIN
product p1_ ON p1_.productid = a2_.accessoryid AND (p0_.productid IN (11224))
除了将accessory_to_product表连接两次外,这几乎是正确的。有没有人给我一个提示?实际上我应该选择FROM accessoires然后加入产品,但由于这是与产品的关系,这是不可能的。
答案 0 :(得分:0)
终于搞定了。我的关系不正确:
/**
*
* @var array
*
* @ORM\ManyToMany(targetEntity="Product", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="accessory_to_product",
* joinColumns={@ORM\JoinColumn(name="accessoryid", referencedColumnName="productid")},
* inverseJoinColumns={@ORM\JoinColumn(name="accessoryid", referencedColumnName="productid", unique=false)});
*/
需要:
/**
*
* @var array
*
* @ORM\ManyToMany(targetEntity="Product", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="accessory_to_product",
* joinColumns={@ORM\JoinColumn(name="accessoryid", referencedColumnName="productid")},
* inverseJoinColumns={@ORM\JoinColumn(name="productid", referencedColumnName="productid", unique=false)});
*/
因为accessory_to_product表有两列,accesoryid和productid。以下代码:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('p')
->from('BestBuy\Entity\Product', 'p')
->where($qb->expr()->in('a.productid', ':products'))
->leftJoin('p.accessories', 'a')
->setParameter('products', $products);
在SQL中进行以下查询:
SELECT
p0_.productid AS productid0,
p0_.title AS title1,
p0_.description AS description2,
p0_.insertdate AS insertdate3,
p0_.price AS price4,
p0_.model AS model5,
p0_.categoryid AS categoryid6,
p0_.deliverytimeid AS deliverytimeid7,
p0_.status AS status8,
p0_.weight AS weight9,
p0_.pagetitle AS pagetitle10,
p0_.metadescription AS metadescription11,
p0_.youtubecode AS youtubecode12
FROM
product p0_
LEFT JOIN
accessory_to_product a2_ ON p0_.productid = a2_.accessoryid
LEFT JOIN
product p1_ ON p1_.productid = a2_.productid
WHERE
p1_.productid IN (11224)
与原版略有不同,但会给出完全相同的结果!