Query Builder 中的 Symfony 实体字段类型 where 子句不适用于一对多自引用关联

Symfony Entity Field Type where clause in Query Builder not working on One-To-Many self referencing association

我有一个名为 "InterestGroup" 的实体,它具有属性形式为 "children"(一对多)和 "parent"(多对一)的自引用关联(邻接列表) ).

在为 InterestGroup 设置表单类型时,我试图为 属性 父级提供一个 select 列表,其中包含所有 'top level' 兴趣组的选择(那些其 'parent' 属性 为空)。当我将 where 子句和 null 参数添加到 EntityType 字段的 query_builder 时,它总是 return 什么都没有,即使我有几个顶级(父级为空)兴趣组仍然存在。如果我删除 where 子句,它将 return table 中的所有 InterestGroups。我很难理解为什么 where 子句不起作用。

这是有问题的字段:

->add('parent',EntityType::class,
    array(
        'placeholder' => 'Top Level (No Parent)',
        'required' => false,
        'class' => 'Common\ContentBundle\Entity\InterestGroup',
        'query_builder' => function (EntityRepository $er) {
            return $er->createQueryBuilder('ig')
              ->where('ig.parent = :n')
              ->setParameter('n',null)
              ->orderBy('ig.title', 'ASC');
        },
        'choice_label' => 'title'
    )
)

以上将 return 一个空的 select 菜单。通过删除 where 子句和 setparameter,我得到了所有 InterestGroup 实体,包括所有具有 null parents 的实体。

以下是 InterestGroup

的实体 Class
<?php

namespace Common\ContentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * InterestGroup
 *
 * @ORM\Table(name="interest_group")
 * @ORM\Entity(repositoryClass="Common\ContentBundle\Repository\InterestGroupRepository")
 */
class InterestGroup
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255, unique=true)
     * @Assert\NotBlank(message="This is a required field.")
     */
    private $title;

    /**
     * @ORM\OneToMany(targetEntity="InterestGroup", mappedBy="parent")
     */
    private $children;

    /**
     * @ORM\ManyToOne(targetEntity="InterestGroup", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    private $parent;

    /**
     * @Gedmo\Slug(fields={"title"})
     * @ORM\Column(length=128, unique=true)
     */
    private $slug;

    // ...
    /**
     * @ORM\ManyToMany(targetEntity="Product", mappedBy="interestGroups")
     */
    private $products;


    /**
     * InterestGroup constructor.
     */
    public function __construct()
    {
        $this->children = new ArrayCollection();
        $this->products = new ArrayCollection();

    }

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @param string $title
     */
    public function setTitle($title)
    {
        $this->title = $title;
    }


    /**
     * @return mixed
     */
    public function getSlug()
    {
        return $this->slug;
    }

    /**
     * @return mixed
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * @param mixed $children
     */
    public function setChildren($children)
    {
        $this->children = $children;
    }

    /**
     * @return mixed
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * @param mixed $parent
     */
    public function setParent($parent)
    {
        $this->parent = $parent;
    }

    /**
     * @return mixed
     */
    public function getProducts()
    {
        return $this->products;
    }
}

和表格类型Class:

<?php

namespace Common\ContentBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;

class InterestGroupType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title',TextType::class)
            ->add('parent',EntityType::class,
              array(
                'placeholder' => 'Top Level (No Parent)',
                'required' => false,
                'class' => 'Common\ContentBundle\Entity\InterestGroup',
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('ig')
                      ->where('ig.parent = :n')
                      ->setParameter('n',null)
                      ->orderBy('ig.title', 'ASC');
                },
                'choice_label' => 'title'
              )
            )
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Common\ContentBundle\Entity\InterestGroup'
        ));
    }
}

提前致谢!

在此处检查您的代码:

return $er->createQueryBuilder('ig')
          ->where('ig.parent = :n') // <---
          ->setParameter('n',null) // <--- 
          ->orderBy('ig.title', 'ASC');

等同于:

... WHERE ig.parent = NULL ...

因此,此查询总是 returns 空数据集。

正确的代码:

return $er->createQueryBuilder('ig')
          ->where('ig.parent IS NULL')
          ->orderBy('ig.title', 'ASC');

使用 IS NULL 检查空值。

此问题与what is "=null" and " IS NULL"

有关