2015-01-07 4 views
0

У меня возникла проблема с созданием SQL-запроса с помощью CreateQueryBuilder.INNER JOIN with Doctrine «createQueryBuilder» в SF2

У меня есть 2 таблицы:

  • Таблица статьи с полями: articleID (PK), tag, created, userID (FK)
  • Таблица articlelocale с полями: articlelocaleID (PK), articleID (FK), title, body, locale, translated

В моей articlelocale таблице у меня есть, что ссылки FK к моей статье.

Теперь я хотел бы выбрать статьи, начиная с таблицы статей, где locale == ... (from articlelocale table).

Это мое начало, но я не могу понять:

$a = $this->createQueryBuilder('a') 
    ->select('a') 
    ->innerJoin('a.articleid', 'ai', 'WITH', 'ai.articleid = :articleid') 
    ->where('ai.locale = :locale') 
    ->setParameter('locale', $locale) 
    ->addOrderBy('a.created', 'DESC'); 

Чем больше я стараюсь, тем больше ошибок я получаю .... Что я делаю не так?

UPDATE:

Спасибо за помощь! Я добавил это в моей статье Entity:

/** 
* @ORM\OneToMany(targetEntity="DX\MurisBundle\Entity\Articlelocale", mappedBy="articleid", cascade={"persist", "remove", "merge"}, orphanRemoval=true) 
*/ 
protected $articlelocale; 

/** 
* Set articlelocale 
* 
* @param \DX\MurisBundle\Entity\Articlelocale $articlelocale 
* @return Articlelocale 
*/ 
public function setArticlelocale(\DX\MurisBundle\Entity\Articlelocale $articlelocale = null) 
{ 
    $this->articlelocale = $articlelocale; 

    return $this; 
} 

/** 
* Get articlelocale 
* 
* @return \DX\MurisBundle\Entity\Articlelocale 
*/ 
public function getArticlelocale() 
{ 
    return $this->articlelocale; 
} 

Это соотношение между Article<->ArticleLocale в моем Articlelocale Entity:

/** 
* @var \DX\MurisBundle\Entity\Article 
* 
* @ORM\ManyToOne(targetEntity="DX\MurisBundle\Entity\Article") 
* @ORM\JoinColumns({ 
* @ORM\JoinColumn(name="articleID", referencedColumnName="articleID") 
* }) 
*/ 
private $articleid; 

Это запрос в моем ArticleRepository:

$a = $this->createQueryBuilder('a') 
    ->select('a') 
    ->innerJoin('a.articlelocale', 'ai') 
    ->where('ai.locale = :locale') 
    ->setParameter('locale', $locale) 
    ->addOrderBy('a.created', 'DESC'); 

if (false === is_null($limit)) 
    $a->setMaxResults($limit); 

return $a->getQuery() 
    ->getResult(); 

Я не получаю никаких ошибок, но когда я хочу просмотреть мои статьи и получить ArticleLocale следующим образом:

$articles = $em->getRepository('MurisBundle:Article')->getLatestArticles(null, $locale); 

foreach($articles as $article) 
{ 
    dump($article->getArticlelocale()); die; 
} 

Результатом этого является PersistentCollection ... enter image description here

Я хотел бы иметь реальный объект Articlelocale .. Что я делаю неправильно?

Это не большая проблема, но я также получаю NL и EN, но я фильтрую 'where locale == nl'. Но у меня все еще есть два результата.

+0

В запросе вы должны использовать имя свойства, описанное в вашей организации, а не имя вашего поля. –

+0

Имя моей собственности в моей организации - это статья. – nielsv

+0

можете ли вы разместить код своего лица? – Matteo

ответ

1

Вы не можете использовать непосредственно имя столбца таблицы при работе с доктриной, вы должны написать DQL ее отличие от SQL, у вас есть имя свойства, которое вы определили в своих сущностях, и часть соединения должна иметь свойство, указывающее на ваш второй объект, тогда вы можете создать свой запрос в

$DM = $this->getDoctrine()->getManager(); 
$DM->createQueryBuilder('ar') 
    ->select('ar') 
    ->from('Namespace\YourBundle\Entity\Article','ar') 
    ->innerJoin('ar.articlelocale', 'lo') 
    ->where('lo.locale = :locale') 
    ->setParameter(':locale', $locale) 
    ->orderBy('ar.created', 'DESC'); 

И в вашей статье лица должны иметь отношения с Articlelocale сущности что-то вроде

/** 
* @ORM\OneToMany(targetEntity="\Namespace\YourBundle\Entity\Articlelocale", mappedBy="article", cascade={"persist", "remove", "merge"}, orphanRemoval=true) 
*/ 
protected $articlelocale; 

И ваш Articlelocale лица должны указывать обратно Article сущности, как показано ниже

/** 
* @var \Namespace\YourBundle\Entity\Article 
* 
* @ORM\ManyToOne(targetEntity="Namespace\YourBundle\Entity\Article") 
* @ORM\JoinColumns({ 
* @ORM\JoinColumn(name="articleID", referencedColumnName="articleID") 
* }) 
*/ 
protected $article; 

также генерировать Геттеры анс сеттера для перечисленных выше свойств

Редактировать другой способ переписать вы запрашиваете, как

$article= $this->getDoctrine()->getRepository('Namespace\YourBundle\Entity\Article'); 
$article->createQueryBuilder('ar') 
    ->select('ar') 
    ->innerJoin('ar.articlelocale', 'lo') 
    ->where('lo.locale = :locale') 
    ->setParameter(':locale', $locale) 
    ->orderBy('ar.created', 'DESC') 
    ->getQuery() 
    ->getResult(); 
+0

Спасибо за помощь! Я изменил свои сущности и запрос, но теперь я получаю еще одну небольшую ошибку, что может быть проблемой? – nielsv

+0

@nielsv Я добавил другой способ переписать запрос, также как и обновленные псевдонимы –

+0

Я использую запрос в пользовательском репозитории, поэтому у меня нет доступа к -> getDoctrine(), потому что он не расширяет контроллер. Как я могу это исправить? – nielsv

0

В вашем ArticleRepository:

$query = $this->createQueryBuilder('a') 
    ->select('a') 
    ->innerJoin('a.articlesLocale', 'al') 
    ->where('al.articleLocaleId = :localeId') 
    ->setParameter('localeId', $locale) 
    ->addOrderBy('a.created', 'DESC'); 

Ваши объекты должны выглядеть так:

class Article 
{ 
    private $articleId; 

    /** 
    * @var Article 
    * 
    * @ORM\OneToMany(targetEntity="path\to\ArticleLocale", mappedBy="article") 
    */ 
    private $articlesLocale; 

    /** 
    * @return integer 
    */ 
    public function getArticleId() 
    { 
     return $this->articleId; 
    } 

    /** 
    * @return ArticleLocale 
    */ 
    public function getLocale(){ 
     return $this->locale; 
    } 

    /** 
    * @param ArticleLocale $locale 
    */ 
    public function setLocale($locale){ 
     return $this->locale = $locale; 
    } 

} 

class ArticleLocale 
{ 
    private $articleLocaleId; 

    /** 
    * @var ArticleLocale 
    * 
    * @ORM\ManyToOne(targetEntity="path\to\Article", inversedBy="articlesLocale") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="article_id", referencedColumnName="articleId", nullable=false) 
    * }) 
    */ 
    private $article; 

    /** 
    * @return integer 
    */ 
    public function getArticleLocaleId() 
    { 
     return $this->articleLocaleId; 
    } 

    /** 
    * @return Article 
    */ 
    public function getArticles(){ 
     return $this->articles; 
    } 

}