Symfony EasyAdmin中使用SQL SUM分组统计遇数组读取错误求助
解决Symfony EasyAdmin分组求和时的「Cannot read property 'id' from an array」错误
问题原因
当你手动通过addSelect指定字段并执行分组查询时,Doctrine返回的是关联数组而非实体对象。EasyAdmin默认期望操作的是实体实例,会尝试读取实体的id属性,因此抛出该错误。
解决方案
1. 调整查询构建器,返回结构化数组
修改createIndexQueryBuilder,清空默认的实体查询,指定需要的字段并正确分组:
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder { $entityRepository = $this->get(EntityRepository::class); $queryBuilder = $entityRepository->createQueryBuilder($searchDto, $entityDto, $fields, $filters); // 清空默认的实体select,改为自定义字段查询 $queryBuilder->select(); $queryBuilder->addSelect('entity.account') ->addSelect('entity.organizationIdentifier') // 用别名区分聚合结果和原字段 ->addSelect('SUM(entity.countOfChargableIrdis) AS totalCount') ->andWhere('entity.bookedAt IS NULL') // 分组需包含所有非聚合的查询字段,符合SQL规范 ->addGroupBy('entity.organizationIdentifier', 'entity.account'); return $queryBuilder; }
2. 修改字段配置,适配数组结构
在configureFields中,用数组路径([字段名])的方式读取数组中的值:
public function configureFields(string $pageName): iterable { return [ TextField::new('[account]', 'Customer')->setColumns(4), TextField::new('[organizationIdentifier]', 'organization identifier')->setColumns(4), IntegerField::new('[totalCount]', 'Total count of orders')->setColumns(4), ]; }
3. 禁用依赖实体的操作
由于查询返回的是数组而非实体,EasyAdmin的编辑、删除、详情等操作会失效,需要在configureActions中移除这些操作:
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; public function configureActions(Actions $actions): Actions { return $actions ->remove(Crud::PAGE_INDEX, Crud::PAGE_EDIT) ->remove(Crud::PAGE_INDEX, Crud::PAGE_DELETE) ->remove(Crud::PAGE_INDEX, Crud::PAGE_DETAIL); }
说明
- 必须保证
GROUP BY子句包含所有非聚合的查询字段,否则会触发SQL模式错误(仅适用于MySQL等严格模式) - 聚合字段使用别名避免与原实体字段名冲突,同时让字段配置更清晰
- 数组路径的写法是EasyAdmin专门用于处理非实体数据源的语法
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

