繁体   English   中英

Symfony2 ManyToMany在一个查询中

[英]Symfony2 ManyToMany in one query

我有2个与ManyToMany相关的实体

class Product
{

/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=100, unique=true)
 */
private $name;

/**
 * @ORM\ManyToMany(targetEntity="ProductTransfer", inversedBy="product")
 * @ORM\JoinTable(name="products_transfers")
 */
private $transfers;

第二个

class ProductTransfer
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var int
 *
 * @ORM\Column(name="stock_from_id", type="integer")
 */
private $stockFromId;

/**
 * @var int
 *
 * @ORM\Column(name="stock_to_id", type="integer")
 */
private $stockToId;

/**
 * @var int
 *
 * @ORM\Column(name="product_id", type="integer")
 */
private $productId;

/**
 * @ORM\ManyToMany(targetEntity="Product",mappedBy="transfers")
 */
private $product;

所有作品都很棒,附加表是由Doctrine创建的。
但是,当我尝试从ProductTransfers获取所有行时,我在探查器中看到,每一行都需要一个带有2个联接的查询。
因此,对于5000种产品,确实会有很多查询。

有没有办法像“干净的SQL”一样在一个查询中将它们全部获得? 如果使用教义无法做到这一点,那么实现这一目标的最佳方法是什么?

喜欢:

SELECT * FROM product_transfer pt
LEFT JOIN products_transfers pts ON pt.product_id=pts.product_id
LEFT JOIN product p ON pts.product_id=p.id;

编辑:在存储库中创建方法

public function loadTransfersByStock($stockId)
{

    $q = $this->getEntityManager()
        ->createQuery(
            'SELECT pt,p FROM AppBundle:ProductTransfer pt
            LEFT JOIN AppBundle:Product p WITH pt.productId=p.id
            WHERE pt.stockToId = :stockId'
        );

    return $q->setParameter('stockId', $stockId)->getResult();
}

然后结果是

ProductsController.php on line 495:
array:3 [▼
  0 => ProductTransfer {#1071 ▶}
  1 => Product {#1084 ▶}
  2 => ProductTransfer {#1099 ▶}
]

默认情况下,Doctrine在对象关系中使用延迟加载-关系的行仅在您尝试访问它们时才加载。 如果您知道将需要所有相关的行,请尝试更改为热切获取。

/**
 * @ORM\ManyToMany(targetEntity="ProductTransfer", inversedBy="product", fetch="EAGER")
 * @ORM\JoinTable(name="products_transfers")
 */

当您像在存储库中那样编写查询时,您将跳过学说“想要”您编写它的方式。 因此,除此以外,我将执行以下操作:

//ProductTransferRepository.php
$qb = $this->createQueryBuilder('pt');
$qb
    ->select('pt, p') // here you can choose the columns you want if you don't need everything from both tables
    ->leftJoin('pt.product', 'p')
    ->where('pt.stockToId = :stockId')
    ->setParameter('stockId', $stockId)
;
return $qb
    ->getQuery()
    ->getArrayResult()
;

使用getArrayResult可以将结果作为数组而不是对象来获取,尤其是因为您有很多查询时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM