我有4个表,实体中的属性都相应地映射。我试图根据选定的标签查询文章。
articles => id, title, author_id - NAMESPACE AppBundle/Enity/Article
tags => id, name - NAMESPACE AppBundle/Entity/Tag
article_tags => article_id, tag_id
authors=> id, name - NAMESPACE AppBundle/Entity/Author
我已经弄明白了如何在article_tags表格中获取所有与哪些标签有相关ID的文章,并按作者ID进行过滤。在SQL中,我的查询看起来像这样。经过测试和工作。
SELECT
articles.title, articles.id, authors.name
FROM
article_tags
INNER JOIN tags
ON article_tags.tag_id = tags.id
INNER JOIN articles
ON article_tags.article_id = article.id
INNER JOIN authors
ON authors.id = articles.author_id
WHERE
tags.id IN (1,2)
我正在尝试构建一个代表上述sql的查询。到目前为止,我的理解是,学说将根据实体中的ORM断言自动获取所需的关联。但是,我不确定如何将其他实体带入查询。这是我到目前为止所做的。
我在文章回购中的代码是:
$qb = $this->createQueryBuilder('ar')
->select('ar.title, ar.id, au.name')
->from('article_tags', 'at')
->innerJoin('tags', 't', 'WITH', 'at.tag_id = t.id')
->innerJoin('ar', 'WITH', 'at.article_id = ar.id')
->innerJoin('authors', 'au', 'WITH', 'au.id = ar.author_id')
->where('at.id IN (1,2)');
return $qb->getQuery()->getResult();
我已尝试使用' ON'和' WITH'关键字。
我的错误是: [语义错误]第0行,第76列附近'标记t WITH at.tag_id':错误:类'标记'没有定义。
答案 0 :(得分:2)
当您与Doctrine ORM联接时,您不应该指定连接条件,因为它应该在您的实体的元数据中。
因此,在您的实例中,您有与标签和作者相关的文章,如果您想要标签和作者以及您的文章,您的查询应该类似于:
// this is in the article repository I'm guessing?
$qb = $this->createQueryBuilder('ar');
$qb->addSelect([ 't', 'au' ])
->join('ar.tags', 't')
->join('ar.authors', 'au')
->where($qb->expr()->in('a.tags', ':tags'))
->setParameter('tags', [ 1, 2 ]);
因此,两个连接语句都在实体的属性上,在本例中为tags
和authors
。在您的文章实体中,您需要根据the documentation将这些设置为关联。元数据定义了文章与标签和作者的关系,而Doctrine将(通常)填补空白。您的查询看起来仍然在思考SQL而不是实体和Doctrine(和DQL)。
作为旁注,上面不是很好的查询,因为返回的行数将等于标签和作者的数量,你最好不要额外做查询选择中的实体,然后抓取标签(例如通过执行$article->getTags()
)。