2016-02-01 14 views
1

我想通過查詢生成器構建查詢。Symfony - Doctrine QueryBuilder生成錯誤的sql

$photosQuery = $photoRepository->createQueryBuilder('p') 
     ->join('AppBundle:User', 'u') 
     ->where('LOWER(p.title) LIKE :phrase OR LOWER(u.username) LIKE :phrase AND p.isActive = :isActive AND p.isModerated = :isModerated') 
     ->setParameter('phrase', '%'.strtolower($phrase).'%') 
     ->setParameter('isActive', true) 
     ->setParameter('isModerated', true) 
     ->getQuery(); 

它給了我

SELECT p0_.id AS id_0, 
     p0_.title AS title_1, 
     p0_.description AS description_2, 
     p0_.name AS name_3, 
     p0_.creation_date AS creation_date_4, 
     p0_.edit_date AS edit_date_5, 
     p0_.is_moderated AS is_moderated_6, 
     p0_.moderation_date AS moderation_date_7, 
     p0_.is_active AS is_active_8, 
     p0_.user_id AS user_id_9, 
     p0_.category_id AS category_id_10 
FROM photos p0_ 
INNER JOIN users u1_ ON (LOWER(p0_.title) LIKE ? 
         OR LOWER(u1_.username) LIKE ? 
         AND p0_.is_active = ? 
         AND p0_.is_moderated = ?) 

爲什麼我在加入ON()部分WHERE參數,而不是傳統的WHERE

謝謝!

+0

嘗試將您的連接更改爲' - >連接('p.user','u')' –

+0

Jason,謝謝! – Tigran

+0

我增加了一個答案,更具體地解釋了爲什麼會發生這種情況,以及將來如何解決這個問題,而不是犯同樣的錯誤。 –

回答

1

Doctrine提供了一個低級別數據庫連接的包裝,它不必具有DQL中的所有功能。因此,它模擬一些功能(例如命名參數,或將數組參數拆分爲多個單獨的值)。

您在這裏看到的是:在原始查詢中,命名參數被轉換爲位置參數。儘管如此,Doctrine仍然知道映射是什麼,並且在將查詢和參數發送到服務器時能夠正確地對它們進行排序。

0

因此,jbafford的答案解釋了一些信息原則,但沒有明確回答爲什麼使用ON而不是WHERE,這是由於一個常見的錯誤(我最近也提出這個錯誤)。

在您的查詢,當您使用

->join('AppBundle:User', 'u') 

你只是告訴你需要加入對User表查詢生成器,但它不知道具體要加入的user您的Photo實體的關聯。你可能會認爲 - 爲什麼這不會自動發生?那麼,想象一下,如果您的桌面上還有另外一個關聯到User實體的關聯(可能是createdBy字段或類似關鍵字)。在這種情況下,學說不會知道你想要的聯想。

所以,而是做正確的事是直接在您的加入協會,而不是一般的實體,像這樣:

->join('p.user', 'u') 

,然後學說將處理其餘部分。我實際上無法告訴你爲什麼它使用where()條件進行連接,除非它只是假設這就是你想要的,因爲它需要知道如何連接

所以,請記住,當您加入一個您已經定義的關聯時,請按照您的實體中所述的方式加入關聯,而不是以直接SQL格式將其加入表格。