假设我的Symfony2项目中有两个实体:Category
和Article
(一个包含许多文章的类别)。
在我的CategoryRepository
中,我有这个方法:
findAllDummy(){
return $this->createQueryBuilder('c')
->leftJoin('c.Articles a')
->getQuery()->getResult();
}
如果我没记错的话,在Symfony1.4 (以及相应的Doctrine版本)中,返回的对象将由相应的Article
对象填充它们的“文章”属性。现在,在Symfony2中,返回代理对象。
因此,如果我遍历特定类别的文章,将执行与迭代一样多的查询。
foreach($category->getArticles() as $article){
echo $article->getDoctrine()
->getRepository('')getTitle();
}
我知道这是Doctrine2.1的默认延迟加载行为。
问题1:这是一个更好的解决方案吗?%n个查询,而不是% 1。
我尝试通过执行以下操作来强制执行紧急加载:
findAllDummy(){
return $this->createQueryBuilder('c')
->leftJoin('c.articles a')
->getQuery()
->setFetchMode('Category', 'articles', 'EAGER')
->getResult();
}
但结果仍然是一样的。
问题2:如何在Doctrine2中强制强制加载?
发布于 2012-01-12 23:56:17
您正在加入一个表,但没有从中选择任何内容。将->addSelect('a')
添加到查询构建器中。考虑以下两个SQL查询,以了解它们之间的区别:
SELECT a.id, a.title
FROM article a
JOIN category c ON a.category_id = c.id
WHERE a.id = 123;
SELECT a.id, a.title, c.id, c.name
FROM article a
JOIN category c ON a.category_id = c.id
WHERE a.id = 123;
with /lazy连接与DQL查询无关。它定义了使用$articleRepository->find(123)
时应该加载的内容。
发布于 2015-08-27 22:25:54
在您试图“强制立即加载”的部分中,问题可能是您使用了带有错误的$fetchMode
参数变量类型的fetchMode
方法。您传递了一个字符串'EAGER'
,但是该方法不需要字符串,而需要一个整数。
该方法需要来自ClassMetadata
类的常量:
/**
* Specifies that an association is to be fetched when it is first accessed.
*/
const FETCH_LAZY = 2;
/**
* Specifies that an association is to be fetched when the owner of the
* association is fetched.
*/
const FETCH_EAGER = 3;
在教义文档章节14.7.6.6中。在DQL中临时更改fetch模式你可以看到一个如何使用的示例:
$query->setFetchMode("MyProject\User", "address", \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER);
因此,要么传递对常量的引用,要么传递与您想要使用的模式相对应的整数。
发布于 2012-01-12 23:38:57
这是一个更好的解决方案,因为连接是一个比简单查询更昂贵的过程。虽然它可能看起来效率很低,但它并不是一种浪费,而且当您不加载每个相关对象的每一个比特时,它很快就会变得更有效。
https://stackoverflow.com/questions/8836384
复制相似问题