2012-11-13 59 views
0

2選擇成員,我有兩個實體一對多和多對一關係學說使用收集

條具有一對多標籤

ArticleTag有多對一文章

$articleTags = $em->getRepository('Model\ArticleTag') 
    ->findBy(array('article' => $articleId)); 

$qb->select('a') 
    ->from('\\Model\\Article', 'a') 
    ->where(':tags MEMBER OF a.tags') 
    ->setParameter('tags', $articleTags); 

該查詢返回錯誤:

An exception occurred while executing 
    SELECT .. FROM article a0_ WHERE EXISTS (SELECT 1 FROM article_tag a1_ WHERE a0_.id = a1_.article_id AND a1_.id = ?, ?, ?)' with params {"1":8,"2":9,"3":10} 
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 9, 10)' at line 1 

它有任何使用'in''instead'='in expression'a1_.id =?,?,?'

回答

2

這個問題是舊的,但這裏有一個答案:

如果使用數組作爲輸入,這樣您可以使用:

...
->where('a.id IN (:tag_ids)')
->setParameter('tag_ids', $articleTags)
...

0

正如lordjansco說,老問題,但我想稍微向其他人發現它。

要擴展lordjancso的答案,因爲a.id指的是文章ID而不是標籤ID。您需要在a.tags上使用IN執行內部連接,以從相關標籤中檢索文章。

像這樣。

$articleTags = $em->getRepository('Model\\ArticleTag') 
    ->findBy(array('article' => $articleId)); 

$qb = $em->createQueryBuilder(); 
$query = $qb->select('a') 
    ->from('\\Model\\Article', 'a') 
    ->innerJoin('a.tags', 't', 'WITH', 't.id IN (:tags)') 
    ->setParameter('tags', $articleTags) 
    ->getQuery(); 
$result = $query->getResult(); 

但是,因爲你知道文章ID已經,沒有必要創建另一個查詢來檢索標籤的文章。

如果您使用的是Doctrine2 ORM,並且您的實體設置爲ManyToOne,您應該可以直接從文章中調用getTags

$article = $em->getRepository('Model\\Article')->findOneById($articleId); 
$articleTags = $article->getTags(); 

或者如果需要的話,你也可以遍歷每個標籤。

$articleTags = $em->getRepository('Model\\ArticleTag') 
    ->findBy(array('article' => $articleId)); 

foreach ($articleTags as $articleTag) { 
    $article = $articleTag->getArticle(); 
} 

確保您有一個雙向one-to-many關聯配置爲您的實體。

http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional

像這樣:

use \Doctrine\Common\Collections\ArrayCollection; 

/** @Entity **/ 
class Article 
{ 
    /** 
    * @var ArrayCollection|ArticleTags[] 
    * @ORM\OneToMany(targetEntity="ArticleTags", mappedBy="article") 
    */ 
    private $tags; 

    public function __construct() 
    { 
     $this->tags = new ArrayCollection; 
    } 

    /** 
    * @return ArticleTags[]|ArrayCollection 
    */ 
    public function getTags() 
    { 
     return $this->tags; 
    } 
} 
/** @Entity **/ 
class ArticleTags 
{ 
    /** 
    * @var Article 
    * @ORM\ManyToOne(targetEntity="Article", inversedBy="tags") 
    * @ORM\JoinColumn(name="article", referencedColumnName="id") 
    */ 
    private $article; 
}