2016-07-23 115 views
2

我對來自Kohana背景的Symfony非常陌生,我有一段時間習慣了Doctrine。Doctrine的createQueryBuilder繞過Entities getter方法嗎?

目前我有一個產品表,我內心使用createQueryBuilder連接其他一些表,並且需要在產品實體的getter方法中添加一些額外的邏輯。但是,似乎getter方法甚至沒有被使用。下面是我的一些代碼片段:

//From AppBundle\Controller\ProductController 

$repository = $this->getDoctrine()->getRepository('AppBundle:Product'); 
$products = $repository->findWithLimitNew(24); 

//From AppBundle\Repositories\ProductRepository 
public function findWithLimitNew($limit=1) 
{ 
    $em = $this->getEntityManager(); 
    $qb = $em->createQueryBuilder(); 
    $qb->select('p.name', 'p.id', 'p.slug', 'pc.name AS catname') 
     ->from('AppBundle\Entity\Product', 'p') 
     ->innerJoin(
      'AppBundle\Entity\ProductAttributes', 
      'pa', 
      \Doctrine\ORM\Query\Expr\Join::WITH, 
      'p.id = pa.productId' 
     ) 
     ->innerJoin(
      'AppBundle\Entity\ProductCategories', 
      'pc', 
      \Doctrine\ORM\Query\Expr\Join::WITH, 
      'pa.value = pc.id' 
     ) 
     ->where('pa.type = 1') 
     ->where('pa.default = 1') 
     ->setMaxResults($limit); 

    return $qb->getQuery()->getResult(); 
} 

// From AppBundle\Entity\Product 
/** 
* Get name 
* 
* @return string 
*/ 
public function getName() 
{ 
    #return $this->name; //<--Commenting this out for now 
    return 'Some stupid string'; 
} 

// From index.twig.html 
{% for product in products %} 
<h1>{{product.name}}</h1> 
{% endfor %} 

現在你可以看到我有吸氣getName()方法返回一個字符串,但在視圖渲染我得到的產品名稱,而不是我的字符串返回。是什麼賦予了?

+1

正如你懷疑的那樣,當水合一個實體(即從數據庫檢索)時,Doctrine 2使用反射來直接設置實體屬性。所有方法(包括構造函數)都被忽略。而DQL不是SQL。我很驚訝你的查詢返回任何東西。 – Cerad

+0

@Cerad我的查詢來自一個Doctrine網站,查詢工作正常。當然,我修改了我的表名。 – pogeybait

+0

AppBundle \ Entity \ Product中的標籤爲pubic的是「名稱」字段嗎?如果是這種情況,可能是因爲樹枝認爲該屬性是公共的,並且不會打擾調用吸氣劑。儘量讓它變得私密並且讓吸氣者公開 – valepu

回答

0

@Cerad有一個觀點。乍一看,你的查詢看起來像DQL而不是QB。但是現在我知道你的代碼是正確的,可以簡化您的QueryBuilder(QB)代碼相當多:

$qb->select('p') 
    ->from('AppBundle:Product', 'p') 
    ->innerJoin(
     'AppBundle:ProductAttributes', 
     'pa', 
     'WITH', 
     'p.id = pa.productId' 
) 
    ->innerJoin(
     'AppBundle:ProductCategories', 
     'pc', 
     'WITH', 
     'pa.value = pc.id' 
) 
    ->where('pa.type = 1') 
    ->andWhere('pa.default = 1') 
    ->setMaxResults($limit); 

注意我用的是「andWhere」,但你原來有一個額外的「在那裏」。我感到驚訝的作品,並沒有拋出和錯誤。

此外,我認爲主要的問題是,你只需要瞭解返回的結果。然後在你的樹枝中,你不會調用屬性,而是調用如下的吸氣劑:

// From index.twig.html 
{% for product in products %} 
    <h1>{{ product.getName }}</h1> 
{% endfor %} 

你可以嘗試這些改變嗎?我認爲在樹枝模板中調用getter是個問題。

這可能行不通。讓我們知道如果它不。

+0

如果關係全部被映射,那麼innerJoin('p.attributes','pa')就是所需要的。無需拼出含有東西,也不需要指定產品屬性類。 – Cerad

+0

我明白你在說什麼@Cerad和我完全同意你的評論(因此也是upvote)。這個操作對Symfony來說是新的,我只是假設他的查詢按照它的方式工作。只試圖幫助解決這個問題。一旦他熟悉「更簡單」的方法,他可以改變他的設計。 –

+0

@AlvinBunk當我嘗試更改{{product.getName}},甚至將圓括號添加到函數時,我得到了可怕的數組來轉換字符串錯誤。根據我的理解,product.name實際上應該是調用getter getName(),但在Cerad所說的這種查詢類型的情況下,它直接將結果水化爲數組而不使用getter。 – pogeybait