Symfony 5 - Easy Admin 3:关联实体有这么多数据时,AssociationField 的负载很重

Posted

技术标签:

【中文标题】Symfony 5 - Easy Admin 3:关联实体有这么多数据时,AssociationField 的负载很重【英文标题】:Symfony 5 - Easy Admin 3: Heavy load on AssociationField when the associated entity have so many data 【发布时间】:2021-12-13 13:05:25 【问题描述】:

我有以下 CrudController:

<?php

namespace App\Controller\Admin\Core;

use App\Entity\Core\Role;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\SlugField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class RoleCrudController extends AbstractCrudController

    public static function getEntityFqcn(): string
    
        return Role::class;
    

    public function configureFields(string $pageName): iterable
    
        return [
            TextField::new('name', 'Name')
                ->setRequired(true)
                ->setMaxLength(255)
                ->setHelp('The role name, prefix with: ROLE_'),
            SlugField::new('systemName', 'System Name')
                ->setRequired(true)
                ->setTargetFieldName('name')->setFormattedValue(function ($value) 
                    return strtoupper($value);
                ),
            TextEditorField::new('description', 'Description'),
            IntegerField::new('level', 'Role Level')->setHelp('Provide the role level'),
            AssociationField::new('subsOfRole', 'Parent Role'),
            ChoiceField::new('type', 'Role Relation Type')
                ->setChoices([
                    'User' => 1,
                    'Job Title' => 2,
                    'Unit' => 3,
                    'Office' => 4,
                    'Echelon' => 5,
                    'Office Type' => 6,
                    'user Group' => 7,
                    'Job Title + Unit' => 8,
                    'Job Title + Office' => 9,
                    'Job Title + Unit + Office' => 10,
                    'Job Title + Unit + Office Type' => 11
                ])
                ->setRequired(true),
            AssociationField::new('users', 'Users')
                ->setHelp('Must be filled when you choose User as Role Relation Type')
                ->hideOnIndex(),
            AssociationField::new('groups', 'Groups')
                ->setHelp('Must be filled when you choose Group as Role Relation Type')
                ->hideOnIndex(),
            AssociationField::new('jobTitles', 'Job Title')
                ->hideOnIndex(),
            AssociationField::new('units', 'Unit')
                ->hideOnIndex(),
            AssociationField::new('offices', 'Offices')
                ->hideOnIndex(),
            AssociationField::new('echelons', 'Echelons')
                ->hideOnIndex(),
            AssociationField::new('officeTypes', 'Office Types')
                ->hideOnIndex(),
        ];
    

当我们有小数据时它运行良好,但是当我们用数万个数据对用户实体/其他相关实体进行测试时,CRUD 页面很慢。

有什么方法可以改变 AssociationField 的工作方式吗?还是为了提高用户端(浏览器)的性能?

背景: 我使用 Symfony 5.3.9 和 EasyAdmin 3.5.10,这是我写这篇文章时的最新版本

谢谢

【问题讨论】:

你看过autocomplete吗?这样数据就受限于用户过滤的子集,而不是将所有记录作为选择元素。 【参考方案1】:

按照 Will B. 的建议,我检查了 autocomplete 功能并进行了尝试。这就是解决方案。

我之前的代码变成了这样(参见 ->autocomplete() 实现):

<?php

namespace App\Controller\Admin\Core;

use App\Entity\Core\Role;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\SlugField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class RoleCrudController extends AbstractCrudController

    public static function getEntityFqcn(): string
    
        return Role::class;
    

    public function configureFields(string $pageName): iterable
    
        return [
            TextField::new('name', 'Name')
                ->setRequired(true)
                ->setMaxLength(255)
                ->setHelp('The role name, prefix with: ROLE_'),
            SlugField::new('systemName', 'System Name')
                ->setRequired(true)
                ->setTargetFieldName('name')->setFormattedValue(function ($value) 
                    return strtoupper($value);
                ),
            TextEditorField::new('description', 'Description'),
            IntegerField::new('level', 'Role Level')->setHelp('Provide the role level'),
            AssociationField::new('subsOfRole', 'Parent Role')
                ->autocomplete(),
            ChoiceField::new('type', 'Role Relation Type')
                ->setChoices([
                    'User' => 1,
                    'Job Title' => 2,
                    'Unit' => 3,
                    'Office' => 4,
                    'Echelon' => 5,
                    'Office Type' => 6,
                    'user Group' => 7,
                    'Job Title + Unit' => 8,
                    'Job Title + Office' => 9,
                    'Job Title + Unit + Office' => 10,
                    'Job Title + Unit + Office Type' => 11
                ])
                ->setRequired(true),
            AssociationField::new('users', 'Users')
                ->autocomplete()
                ->setHelp('Must be filled when you choose User as Role Relation Type')
                ->hideOnIndex(),
            AssociationField::new('groups', 'Groups')
                ->autocomplete()
                ->setHelp('Must be filled when you choose Group as Role Relation Type')
                ->hideOnIndex(),
            AssociationField::new('jobTitles', 'Job Title')
                ->autocomplete()
                ->hideOnIndex(),
            AssociationField::new('units', 'Unit')
                ->autocomplete()
                ->hideOnIndex(),
            AssociationField::new('offices', 'Offices')
                ->autocomplete()
                ->hideOnIndex(),
            AssociationField::new('echelons', 'Echelons')
                ->autocomplete()
                ->hideOnIndex(),
            AssociationField::new('officeTypes', 'Office Types')
                ->autocomplete()
                ->hideOnIndex(),
        ];
    

现在负载很好。

谢谢

【讨论】:

以上是关于Symfony 5 - Easy Admin 3:关联实体有这么多数据时,AssociationField 的负载很重的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Symfony Easy admin crud 面板中创建下拉选择?

如何定义输入以在 Easy admin 中保存浮点数?

Symfony 4 EasyAdmin 如何加密密码?

无法使用 symfony 5 安装奏鸣曲管理员

Symfony - Sonata “在管理池中找不到管理服务“app.admin.post”。”

Symfony 3.3.9 - app.user.roles 没有得到 role_admin