2015-07-21 24 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獲取模式減少了觸發完整實體水合的方法的數量。