67 votes

Doctrine findBy 'n'est pas égal'.

Comment faire

WHERE id != 1

En Doctrine ?

J'ai ceci jusqu'à présent

$this->getDoctrine()->getRepository('MyBundle:Image')->findById(1);

Mais comment faire un "ne pas égaler" ?

C'est peut-être idiot, mais je ne trouve aucune référence à ce sujet ?

Merci

75voto

El Yobo Points 7580

Il existe maintenant une approche pour le faire, en utilisant les critères de Doctrine.

Un exemple complet peut être vu dans Comment utiliser une méthode findBy avec des critères comparatifs ? mais une brève réponse suit.

use \Doctrine\Common\Collections\Criteria;

// Add a not equals parameter to your criteria
$criteria = new Criteria();
$criteria->where(Criteria::expr()->neq('prize', 200));

// Find all from the repository matching your criteria
$result = $entityRepository->matching($criteria);

56voto

BADAOUI Mohamed Points 1808

Il n'existe pas de méthode intégrée qui permette de faire ce que vous avez l'intention de faire.

Vous devez ajouter une méthode à votre référentiel, comme ceci :

public function getWhatYouWant()
{
    $qb = $this->createQueryBuilder('u');
    $qb->where('u.id != :identifier')
       ->setParameter('identifier', 1);

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

J'espère que cela vous aidera.

25voto

Luis Points 281

Pour donner un peu plus de flexibilité, j'ajouterais la fonction suivante à mon référentiel :

public function findByNot($field, $value)
{
    $qb = $this->createQueryBuilder('a');
    $qb->where($qb->expr()->not($qb->expr()->eq('a.'.$field, '?1')));
    $qb->setParameter(1, $value);

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

Ensuite, je pourrais l'appeler dans mon contrôleur comme ceci :

$this->getDoctrine()->getRepository('MyBundle:Image')->findByNot('id', 1);

16voto

JCM Points 1259

D'après la réponse de Luis, vous pouvez faire quelque chose qui ressemble davantage à la méthode findBy par défaut.

Tout d'abord, créez une classe de référentiel par défaut qui sera utilisée par toutes vos entités.

/* $config is the entity manager configuration object. */
$config->setDefaultRepositoryClassName( 'MyCompany\Repository' );

Ou vous pouvez éditer ceci dans config.yml

la doctrine : orm : default_repository_class : MonEntreprise \Repository

Ensuite :

<?php

namespace MyCompany;

use Doctrine\ORM\EntityRepository;

class Repository extends EntityRepository {

    public function findByNot( array $criteria, array $orderBy = null, $limit = null, $offset = null )
    {
        $qb = $this->getEntityManager()->createQueryBuilder();
        $expr = $this->getEntityManager()->getExpressionBuilder();

        $qb->select( 'entity' )
            ->from( $this->getEntityName(), 'entity' );

        foreach ( $criteria as $field => $value ) {
            // IF INTEGER neq, IF NOT notLike
            if($this->getEntityManager()->getClassMetadata($this->getEntityName())->getFieldMapping($field)["type"]=="integer") {
                $qb->andWhere( $expr->neq( 'entity.' . $field, $value ) );
            } else {
                $qb->andWhere( $expr->notLike( 'entity.' . $field, $qb->expr()->literal($value) ) );
            }
        }

        if ( $orderBy ) {

            foreach ( $orderBy as $field => $order ) {

                $qb->addOrderBy( 'entity.' . $field, $order );
            }
        }

        if ( $limit )
            $qb->setMaxResults( $limit );

        if ( $offset )
            $qb->setFirstResult( $offset );

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

}

L'utilisation est la même que celle de la méthode findBy, par exemple :

$entityManager->getRepository( 'MyRepo' )->findByNot(
    array( 'status' => Status::STATUS_DISABLED )
);

10voto

Marshall House Points 2028

J'ai résolu ce problème assez facilement (sans ajouter de méthode), je vais donc partager :

use Doctrine\Common\Collections\Criteria;

$repository->matching( Criteria::create()->where( Criteria::expr()->neq('id', 1) ) );

A propos, j'utilise le module Doctrine ORM depuis Zend Framework 2 et je ne suis pas sûr que cela soit compatible dans un autre cas.

Dans mon cas, j'utilisais une configuration d'élément de formulaire comme ceci : pour montrer tous les rôles sauf "guest" dans un tableau de boutons radio.

$this->add(array(
    'type' => 'DoctrineModule\Form\Element\ObjectRadio',
        'name' => 'roles',
        'options' => array(
            'label' => _('Roles'),
            'object_manager' => $this->getEntityManager(),
            'target_class'   => 'Application\Entity\Role',
            'property' => 'roleId',
            'find_method'    => array(
                'name'   => 'matching',
                'params' => array(
                    'criteria' => Criteria::create()->where(
                        Criteria::expr()->neq('roleId', 'guest')
                ),
            ),
        ),
    ),
));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X