Cha*_*yer 4 doctrine symfony doctrine-orm
强制学说从查询JOIN加载嵌套关联实体的最佳方法是什么?
我有多个实体(view,contentType,version,settings),有三个关联级别:
view (primary entity)
contentType (ManyToOne joined on view.contentTypeId = contentType.id)
version (OneToMany joined on version.viewId = view.id)
settings (OneToOne joined on settings.versionId = version.id)
Run Code Online (Sandbox Code Playgroud)
我有一个列表查询所有版本(不是视图)以获取最近修改的版本.但我从view和contentType和访问属性settings.我contentType通过访问view(所以它是两层深).当我在循环中引用这些属性时,我不希望Doctrine Lazy在每个循环中使用N个查询加载每个值.
所以我在查询中加入实体,并选择所有字段.
$versionRepo = $em->getRepository('GutensiteCmsBundle:View\ViewVersion');
$queryBuilder = $versionRepo->createQueryBuilder('e')
->join('e.view', 'view')
->addSelect('view')
->join('view.contentType', 'contentType')
->addSelect('contentType')
->join('e.settings', 'settings')
->where('e.siteId = :siteid')->setParameter('siteId', 1)
->setMaxLimit(25);
Run Code Online (Sandbox Code Playgroud)
第一级链接ARE正确获取,例如version.view.但是,doctrine处理version.settings类似于延迟的负载,并且我将有25个额外的查询来加载每个单独的值.
所以即使我加入settings它仍然是懒惰加载.
Cha*_*yer 11
如果您想避免延迟加载(推荐用于循环),Doctrine建议您在查询时加入实体.但是您还必须将实体添加到SELECT语句中,例如
->join('e.settings', 'settings')
->addSelect('settings')
Run Code Online (Sandbox Code Playgroud)
SELECT查询可以包含联接.有两种类型的JOIN:"常规"连接和"获取"连接.
常规联接:用于限制结果和/或计算聚合值.
获取联接:除了使用常规联接之外:用于获取相关实体并将它们包含在查询的水合结果中.
没有特殊的DQL关键字可以区分常规连接和提取连接.只要连接实体的字段出现在聚合函数之外的DQL查询的SELECT部分中,连接(无论是内连接还是外连接)就会成为"获取连接".否则它是"定期加入".
Doctrine还建议您可以使用查询提示 "水合对象,尽管并非所有列都被提取".
$query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
Run Code Online (Sandbox Code Playgroud)
如果您不想加入,可以查看这些内容.
| 归档时间: |
|
| 查看次数: |
4745 次 |
| 最近记录: |