Symfony6 EasyAdmin4中如何添加二级多对一关联字段
解决EasyAdmin4中显示关联嵌套字段的问题
直接添加嵌套关联字段(无需QueryBuilder)
如果只是要在Dance的CRUD列表/表单里显示Style字段,不用复杂操作,直接利用EasyAdmin对实体关联属性的支持:
// 在DanceCrudController的configureFields方法中 yield AssociationField::new('level'); // 添加Style字段,根据需求选择以下一种 // 若Style实体有__toString方法返回名称,直接使用 yield Field::new('level.style')->setLabel('Style'); // 若需要指定Style的具体属性(比如name) yield Field::new('level.style.name')->setLabel('Style Name');
只要你的实体类里的getter方法正确(Dance::getLevel()、Level::getStyle()、Style::getName()),EasyAdmin会自动解析嵌套关联并显示对应内容。
优化查询性能(避免N+1问题)
如果数据量较大,上面的写法会触发N+1查询(每条Dance都单独查询Level和Style),这时候需要重写createIndexQueryBuilder预加载关联:
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; use EasyCorp\Bundle\EasyAdminBundle\Field\FieldCollection; use EasyCorp\Bundle\EasyAdminBundle\Filter\FilterCollection; use Doctrine\ORM\QueryBuilder; // 在DanceCrudController中 public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder { // 获取默认的查询构建器 $qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); // 预加载Level和Style关联,避免N+1查询 $qb->leftJoin('entity.level', 'l') ->leftJoin('l.style', 's') ->addSelect('l', 's'); return $qb; }
参数说明:
$searchDto:包含当前的搜索、排序等请求参数$entityDto:描述当前实体的元数据(比如实体类名、主键等),并非查询返回的实体对象- 父类返回的QueryBuilder中,根实体的别名固定为
entity,这也是官方示例用entity.first_name的原因
关于entityDto的疑惑
官方示例里用entity.first_name而非entityDto,是因为createIndexQueryBuilder操作的是Doctrine的QueryBuilder,其中根实体的别名是entity,我们通过这个别名编写关联和字段选择逻辑;而entityDto仅用于传递实体的元信息,不是查询的实体实例,无法用它访问实体的具体属性。
内容的提问来源于stack exchange,提问作者Adelraiser
相关产品推荐
相关产品推荐

