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"
有关
我有一个名为 "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"
有关