我有两个实体,具有 oneToMany 和 manyToOne 关系
文章具有一对多标签
文章标签有很多ToOne文章
$articleTags = $em->getRepository('ModelArticleTag')
->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
在表达式"a1_.id = ?, ?, ?"中使用"in"而不是"="有什么办法
这个问题很老,但这里有一个答案:
如果使用数组作为输入,则可以使用 IN
,如下所示:
...
->where( 'a.id IN (:tag_ids)' )
->setParameter( 'tag_ids', $articleTags )
...
正如 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();
}
确保为实体配置了双向一对多关联。
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
这样:
use DoctrineCommonCollectionsArrayCollection;
/** @Entity **/
class Article
{
/**
* @var ArrayCollection|ArticleTags[]
* @ORMOneToMany(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
* @ORMManyToOne(targetEntity="Article", inversedBy="tags")
* @ORMJoinColumn(name="article", referencedColumnName="id")
*/
private $article;
}