2015-12-29 70 views
2

我堅持一個原本很簡單的教義2查詢。我有一個名爲Category的實體,它與自身有一個OneToMany關係(用於父類和子類)。Doctrine2:不能選擇實體通過識別變量而不選擇至少一個根實體別名

/** 
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children") 
*/ 
private $parent; 

/** 
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent") 
*/ 
private $children; 

以下查詢

$q = $this->createQueryBuilder('c') 
      ->leftJoin('c.children', 'cc') 
      ->select('c.name as title, cc') 
      ->where('c.parent IS NULL'); 

失敗,錯誤

而不選擇至少一根實體別名不能選擇通過標識變量實體。

我真的不明白這個問題。如果我省略了->select部分,則該查詢確實有效並且會給出預期的結果。我已經搜索了論壇,但找不到解決方案,這工作。有沒有人有建議?非常感謝。

+0

無論是您的查詢生成器(最有可能)或您的實體有問題。在這兩個上粘貼更多的代碼。 –

+0

這是所有相關章節。查詢生成器代碼位於存儲庫中。我返回$ q-> getQuery() - > getResult(); 就是這樣。 – Performation

+0

回購中的普通查詢生成器就像$ this-> getEntityManager() - > getRepository('MyBundle:Entity') - > createQueryBuilder('c') –

回答

2

你的問題是,你正試圖從類別實體選擇一個字段,同時選擇加入了分類實體的整個對象。與普通SQL不同,使用QueryBuilder組件,您不能僅從您加入的表中選擇一個實體。

如果您希望返回帶有加入子項的主類別對象,則可以執行->select(array('c', 'cc'))或完全忽略->select()的調用。前者會自動在單個查詢中選擇你需要的孩子。如果你想訪問主分類實體上的子項,後者將需要另一個SQL查詢。

如果你想name在對象選擇爲title一個原因,你可以隨時添加其他功能的實體是一個別名用於檢索的名稱,而不必把它寫在你的查詢:

function getTitle() 
{ 
    return $this->getName(); 
} 
+0

感謝您的解釋。有什麼解決方法嗎?我的控制器爲json序列化整個對象,出於安全原因,我只想選擇一些字段。我當然可以在Serializer中做這個選擇,但是沒有辦法只從數據庫收集我想要的數據(即c.name和子對象)嗎? – Performation

+0

串行器組件應允許您在您的實體上設置組,然後序列化這些特定的組。你與孩子的關係問題是可能有多個,否則我會說只是從另一個對象中選擇單獨加入的字段。你可以這樣做,但這取決於你的JSON對象的期望。我會仔細看看Serializer組件,組可能是答案。 –

+0

@JasonRoman你說:「你不僅可以從您加入上表中選擇......」但他不是,是他?他從CC選擇(聯接對象)和c.name ... –

1

您的查詢缺少部分零件。在回購普通查詢生成器是這樣

$q = $this->getEntityManager() 
     ->getRepository('MyBundle:Entity') 
     ->createQueryBuilder(‌​'c') 
     ->select(‌​'c') 
     ->leftjoin(‌​'c.children', 'cc') 
     ->addselect(‌​'cc') 
     ->where(‌​'c.parent is NULL') 
.... 
    return $q; 
+0

謝謝,但是當我改變select('c')來選擇('c.name as title')時,你的查詢會拋出同樣的錯誤。如果從我使用的實體的回購庫中調用,我們查詢的第一部分是等同的。 – Performation

+0

如果您已經在自定義存儲庫中,則不需要調用getEntityManager()和getRepository()調用。 –

相關問題