如何在 Symfony 4 中将 queryBuilder 与 formBuilder 一起使用?

How can I use the queryBuilder with formBuilder in Symfony 4?

我在 Symfony 中使用查询生成器时遇到困难。 像这样,我的 select 框列出了存储在我的实体 "Options":

中的所有数据
$options['class'] = Options::class;
$options['choice_label'] = function ($value) {
    return $value->getName();
};

$formBuilder->add($name, $class, $options);

但我想过滤数据,以便选项仅显示与我的实体的特定 ID 关联的数据 "Fields"。

这是我使用查询生成器的方法:

$options['class'] = Options::class;
$options['choice_label'] = 'id';
$options['query_builder'] = function (EntityRepository $id) {
    return $this->createQueryBuilder('f')
        ->leftJoin('f.fields', 'fi')
        ->where(":id MEMBER OF f.fields")
        ->setParameter(':id', $id)
        ->getQuery()
        ->execute();
};

我收到的错误信息是:

Argument 1 passed to App\Controller\PagesController::App\Controller{closure}() must be an instance of App\Controller\EntityRepository, instance of App\Repository\OptionsRepository given, called in /Users/work/project/vendor/symfony/doctrine-bridge/Form/Type/EntityType.php on line 32

让我们从 EntityRepository 是核心 Doctrine 存储库的事实开始 Doctrine\ORM\EntityRepository; 命名空间。我也怀疑你的项目中还有另一个EntityRepository

所以,第一个错误是错误的类型提示。您应该在控制器之前添加 use Doctrine\ORM\EntityRepository;OptionsRepository 将符合此定义,因为它扩展了 EntityRepository,或者至少,它 应该 .

第二个错误是 ->setParameter(':id', $id) - 您不能将 repository 设置为查询的参数,这是无用的。我不知道什么是 $id 但与任何其他回调函数一样,您可以 use 它。

第三,因为选项名为 query_builder - 你的回调应该 return QueryBuilder,所以删除 ->getQuery()->execute();.

最后正确的代码应该是:

use Doctrine\ORM\EntityRepository;

//....

$options['query_builder'] = function (EntityRepository $er) use ($id) {
    return $er->createQueryBuilder('f')
        ->leftJoin('f.fields', 'fi')
        ->where(":id MEMBER OF f.fields")
        ->setParameter(':id', $id);
};

如果注入整个存储库,还要检查您的实体是否正确设置了 repositoryClass

实体

/**
 * Category.
 *
 * @ORM\Table(name="category")
 * @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
 */
class Category
{
...
}
    

然后

$builder->add('categories', EntityType::class, [
    'class' => Category::class,
    'query_builder' => function (CategoryRepository $categoryRepository) {
        return $categoryRepository->getQueryBuilderForProductCreation();
     },
    'choice_label' => 'name',
]);