Symfony2/Doctrine:SQL 到存储库中查询生成器的 DQL 以制作搜索表单

Symfony2/Doctrine: SQL to DQL for a querybuilder in a repository to make a search form

在我使用 Symfony 的项目中,我需要制作一个具有多标准的搜索表单。 我有实体 Parc 的 select,实体 Typesactivite 的 select 和 Ensembles 的输入文本。

我有这个SQL请求:

SELECT distinct e.nom FROM `ensembles` e, `parcsimmobilier` p, `batiments` b, `batiments_typesactivite` bta, `typesactivite` ta WHERE e.parcsimmobilier_id=p.id AND b.ensembles_id=e.id AND bta.batiments_id=b.id AND bta.typesactivite_id = ta.id AND p.nom="Ville de Dijon" AND ta.type="Sport"

这个 SQL 请求给了我属于第戎公园的所有合奏,那里的 baiments 有 activity 的运动。

我试图在我的 EnsemblesRepository.php 中用 DQL 语法转换这个 SQL 请求,但它没有给我很好的结果,我想我做到了错误:

public function recherche($input) //$input est la valeur entrée dans l'input type text recherche
    {
        $qb = $this ->createQueryBuilder('e')
                    ->select('e.nom')
                    ->addSelect('e.parcsimmobilier')
                    ->from('MySpaceDatabaseBundle:Parcsimmobilier', 'p')
                    ->from('MySpaceDatabaseBundle:Typesactivite', 'ta')
                    ->from('MySpaceDatabaseBundle:Batiments', 'b')
                    ->where('e.parcsimmobilier = p.id')
                    ->andWhere('b.ensembles=b.id')
                    ->andWhere('ta.batiments=b.id')
                    ->andWhere('e.nom LIKE :input')
                    ->setParameters(array(
                        'input' => "%".$input."%"));

        return $qb->getQuery()->getResult();
    }

当我提交表单时,出现以下错误:

[2/2] QueryException: [Semantical Error] line 0, col 16 near 'parcsimmobilier': Error: Invalid PathExpression. Must be a StateFieldPathExpression.

[1/2] QueryException: SELECT e.nom, e.parcsimmobilier FROM MySpace\DatabaseBundle\Entity\Ensembles e, MySpaceDatabaseBundle:Parcsimmobilier p, MySpaceDatabaseBundle:Typesactivite ta, MySpaceDatabaseBundle:Batiments b WHERE e.parcsimmobilier = p.id AND b.ensembles=b.id AND ta.batiments=b.id AND e.nom LIKE :input

如何在我的存储库中发出 DQL 请求?

这是我提交的搜索表单,用于搜索我的实体集成:

class RechercheType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            //Parcsimmobilier
            ->add('parcs:', 'entity', array(
                'class' => 'MySpaceDatabaseBundle:Parcsimmobilier', 
                'property' => 'nom', 
                'empty_value' => 'Choisir le parc immobilier', 
                'required' => true))

            //Typesactivite
            ->add('typesactivite:', 'entity', array(
                'class' => 'MySpaceDatabaseBundle:Typesactivite', 
                'property' => 'type', 
                'empty_value' => 'Choisir le type d\'activite', 
                'required' => false))

            //Ensembles
            ->add('ensemble', 'text', array(
                'attr' => array('placeholder' => 'rechercher'), 
                'required' => false))
            ;

更新

这是我的控制器代码,如果有帮助的话:

public function rechercheEnsemblesAction() {

        $formRecherche = $this->createForm(new RechercheType());

        //si la méthode est bien en POST
        if ($this->get('request')->getMethod() == 'POST' ) 
        {
            $formRecherche->bind($this->get('request'));
            $em=$this->getDoctrine()->getManager();
            $ensemble = $em ->getRepository('MySpaceDatabaseBundle:Ensembles')
                            ->recherche($formRecherche['ensemble']
                            ->getdata());

        }

        return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:rechercheEnsembles.html.twig', array('ensemble' => $ensemble, 'formRecherche' => $formRecherche->createView() ));
    }

让我们尝试逐步执行查询

select标签中,我可以选择parcs的名称required),without 在我的输入文本中为 ensemble 的名称输入一个值。 我的 SQl 请求在 phpMyAdmin:

SELECT distinct e.nom  FROM `ensembles` e, `parcsimmobilier` p where e.parcsimmobilier_id=p.id

这个请求给了我属于 parc 的 所有合奏 ,id 为 1

DQl 中,我在我的存储库中尝试这个 EnsemblesRepository.php:

public function recherche() //$input est la valeur entrée dans l'input type text recherche
{
    $qb = $this ->createQueryBuilder('e')
                ->select('e.nom')
                ->from('MySpaceDatabaseBundle:Parcsimmobilier', 'p')
                ->where('e.parcsimmobilier = p.id')
                ->andWhere('e.nom LIKE :input')
                ->setParameters(array(
                    'input' => "%".$input."%"));

    return $qb->getQuery()->getResult();

}

但 return 我并没有得到好的结果。即使我在构建表单中创建的 select 标签中选择了一个 parc,结果也是我数据库中的所有 Ensemble。

有人可以一步一步地帮助我吗?

如果您需要更多信息,这是我的实体之间的关系。只有两个 classes/entities 有我需要的关系。

Ensemnles.php:

/**
     * @var \Parcsimmobilier
     *
     * @ORM\ManyToOne(targetEntity="Parcsimmobilier")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="parcsimmobilier_id", referencedColumnName="id")
     * })
     */
    private $parcsimmobilier;

Batiments.php:

/**
 * @ORM\ManyToOne(targetEntity="MySpace\DatabaseBundle\Entity\Ensembles")
 * @ORM\JoinColumn(nullable=false)
 */
private $ensembles;

/**
 * @ORM\ManyToMany(targetEntity="MySpace\DatabaseBundle\Entity\Typesactivite")
 * @ORM\JoinColumn(nullable=true)
 */
private $typesactivite;

我真的找不到解决方案,如果您需要,请随时询问更多信息。

感谢您的理解。

您尝试 select 一个带有别名的对象。如果你想 select 标量字段使用 select('entity_alias.field') 但如果你想 select 一个实体你只需指定 table 别名。在您的情况下,您需要 select 'p' 而不是 'e.parcsimmobilier'。

此外,您应该始终加入而不是使用多个 from 语句。这也将允许您根据您的对象模型将那些 where 语句作为 doctrine join 删除,这样您就不需要手动编写那些 Id = id 。

就像我告诉你的那样 here, check the Jquery datatables here,对于你的项目,如果它是为了在 Symfony 中管理你的实体。

然后,您可以将自己的请求与 Jquery、Ajax 和 Symfony 一起使用,以便在 html <table>.

这是一个 .js 的示例,您可以使用它在数据中进行搜索table:

$(document).ready(function() {
    $('#dataTables').DataTable( {
        "dom": '<"toolbar">frtip',
        responsive: true,
        initComplete: function () {
            var api = this.api();
            api.columns().indexes().flatten().each( function ( i ) {
                var column = api.column( i );
                var select = $('<select><option value=""></option></select>')
                    .appendTo( $(column.footer()).empty() )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );
                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    });
                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' )
                });
            });
        }
    });
    $("div.toolbar").html('<b>Example</b>');
});

当然还有 html(不要忘记使用数据表的 table 的结构,所有步骤都在文档中 => 数据表能够增强 HTML table,table 必须有效,格式正确 HTML,带有 header (thead) 和 body (t body)。也可以使用可选的页脚 (tfoot)。):

<table id="dataTables" class="your class or bootstrap class if you are using bootstrap for example">
    <thead>
        <tr>
            <th>Column 1</th>
            <th>Column 2</th>
            ...number you want...
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>{{ entity.field }}</td>
            <td>{{ entity.field2 }}</td>
            ...etc..
        </tr>
    </tbody>
</table>