学说懒惰加载在很多ToMany上。
我在我的博客(帖子)中使用Application'Sonata'ClassificationBundle'Entity'Tag
。
/**
* @var string
*
* @ORM'ManyToMany(targetEntity="'Application'Sonata'ClassificationBundle'Entity'Tag", cascade={"persist"} )
* @ORM'JoinTable( name="blog__post_tag" ,
* joinColumns={ @ORM'JoinColumn( name="blog_post_id", referencedColumnName="id" )},
* inverseJoinColumns={ @ORM'JoinColumn( name="tag_id", referencedColumnName="id" )}
* )
*/
private $tags;
工作代码:
$q = $this->createQueryBuilder('p')
->select('p')
->innerJoin('p.tags', 't')
->where('t = :name')->setParameter('name', $tag)
->andWhere('p.isActive = :active')->setParameter('active', TRUE)
->orderBy('p.id', 'DESC');
return $q->getQuery();
从这个输出查询中,我在树枝中使用标签。所以我必须选择帖子和标签。如果我将代码更新为:
$q = $this->createQueryBuilder('p')
->select('p', 't')
->innerJoin('p.tags', 't')
->where('t = :name')->setParameter('name', $tag)
->andWhere('p.isActive = :active')->setParameter('active', TRUE)
->orderBy('p.id', 'DESC');
return $q->getQuery();
我只有一个标签。
信息:
- 工作代码使用更多的数据库查询(多 1 个查询)。
- 更新的代码有效(不再查询)。但结果我只得到一个标签用于所有帖子。
例:
- "
- 我的第一篇文章"有标签["一","二","三"]。
- "我的第二篇帖子"有标签['二']。
当我使用第一个查询时。工作正常。但是该原则延迟加载标签的代码。我得到 (query1) 的输出 二 = "我的第一篇文章 " 有标签 ['一', '二', '三']。 , "我的第二篇帖子 " 有标签 ['二']。
当我使用第二个查询时。(query2) two = "My First post " 的输出有标签 ['two'], "My Second post " 有标签 ['two']。
我需要帖子中的所有标签。 目前我只从帖子中得到一个标签。
因为内部连接,所以就是这样。关于联接类型的好答案在这里:https://stackoverflow.com/a/6188334/919567
此版本的查询将适用于您:
$q = $this->createQueryBuilder('p')
->select('p', 't')
->leftJoin('p.tags', 't')
->where('t = :name')->setParameter('name', $tag)
->andWhere('p.isActive = :active')->setParameter('active', TRUE)
->orderBy('p.id', 'DESC');
return $q->getQuery();
Sudhakar K,如果这对你有用,你绝对应该使用 Pawel 的答案——我怀疑它会,但仍然如此。
这里的问题是您无法在少于 2 个请求中实现您想要的结果,因为您正在尝试同时执行 2 件事:
- 查找与特定
Tag
相关的所有Post
实体 - 查找与找到的
Post
实体相关的所有Tag
实体
。所有这些都是同一个连接,这似乎完全不可能。由于您对要检索Tag
施加了条件,因此唯一检索到的Tag
实体将是满足该条件的实体,即具有您搜索的名称的Tag
。
您必须对同一个表进行多个联接才能正常工作,即便如此,我怀疑它是否会按您想要的方式工作。
请记住,Doctrine 的设计更多的是为了易用性而不是性能。在使用恕我直言时,试图以这种方式阻止低成本的单一附加请求会适得其反。
知道这一点,我强烈建议您使用第一个解决方案。