2015-07-21 77 views
0

我有一个相当简单的产品数据库,其中品牌有很多产品和颜色,产品有一种或多种颜色。Docrtine多对多数不计数BY

我想选择一个品牌实体的所有颜色以及在单个查询中使用该特定颜色的所有产品的计数,否则我将以30个以上的查询结束页面加载!

主义实体

品牌

class Brand 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", options={"unsigned"=true}) 
    * @ORM\GeneratedValue 
    */ 
    protected $brandId; 

    /** 
    * @ORM\Column(type="string", length=45, unique=true) 
    */ 
    protected $name; 

    /** 
    * @ORM\OneToMany(targetEntity="Product", mappedBy="brand") 
    */ 
    protected $products; 

    /** 
    * @ORM\OneToMany(targetEntity="Colour", mappedBy="brand") 
    */ 
    protected $colours; 
} 

产品

class Product 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", options={"unsigned"=true}) 
    * @ORM\GeneratedValue 
    */ 
    protected $productId; 

    /** 
    * @ORM\Column(type="string", length=45) 
    */ 
    protected $name; 

    /** 
    * @ORM\ManyToOne(targetEntity="Brand", inversedBy="products") 
    * @ORM\JoinColumn(name="brandId", referencedColumnName="brandId", nullable=false) 
    */ 
    protected $brand; 

    /** 
    * @ORM\ManyToMany(targetEntity="Colour") 
    * @ORM\JoinTable(name="productColours", 
    *  joinColumns={@ORM\JoinColumn(name="productId", referencedColumnName="productId")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="colourId", referencedColumnName="colourId")} 
    *) 
    */ 
    protected $colours; 
} 

颜色

class Colour 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", options={"unsigned"=true}) 
    * @ORM\GeneratedValue 
    */ 
    protected $colourId; 

    /** 
    * @ORM\Column(type="string", length=20) 
    */ 
    protected $name; 

    /** 
    * @ORM\ManyToOne(targetEntity="Brand", inversedBy="colours") 
    * @ORM\JoinColumn(name="brandId", referencedColumnName="brandId", nullable=false) 
    */ 
    protected $brand; 
} 

这普拉伊ñSQL这是很容易...

SELECT c.*, b.*, count(p.productId) as productCount 
FROM colours c 
INNER JOIN brands b ON c.brandId = b.brandId 
LEFT JOIN productColours pc ON pc.colourId = c.colourId 
LEFT JOIN products p ON p.productId = pc.productId 
GROUP BY c.colourId 

教义我无法找到解决的办法不增加双向映射到我真的不只是一个产品的计数想要的颜色。

我目前的查询看起来像这样(它不作为没有c.products映射工作)。

$query = $this->getEntityManager()->createQueryBuilder() 
    ->select(
     'c AS colour', 
     'b AS brand', 
     'COUNT(DISTINCT p.productId) AS productCount' 
    ) 
    ->from('Colour', 'c') 
    ->innerJoin('c.brand', 'b') 
    ->leftJoin('c.products', 'p'); 

而且假设上述不会映射品牌进入颜色实体,所以我不能去$colour->getBrand()

+0

为什么你不喜欢双向关联?这可能是你关心的表现吗? – Mark

+0

在整个项目中,我会在很多场合想要完成同样的任务。似乎疯狂做双向计数。 – Nick

+0

如果映射正确,双向关联不会做错。请参阅下面的答案。 – Mark

回答

0

你可以运行一个原生的SQL查询与教条来实现你的目标。这里看一个例子:http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html

第二个选择是使用双向关联。如果您担心性能问题,您可以启用LAZYEXTRA_LAZY提取模式。因此,如果有的话,性能将受到最小程度的影响。

更多extra lazy协会:http://doctrine-orm.readthedocs.org/en/latest/tutorials/extra-lazy-associations.html

在教义协会被认为是默认懒惰。这意味着实体只有在使用时才会被完全加载(例如,财产访问,搜索等)。

extra lazy获取模式减少了触发完整实体水合的方法的数量。