【问题标题】:Doctrine findBy 'does not equal'教义 findBy '不等于'
【发布时间】:2012-12-14 16:32:12
【问题描述】:

我该怎么做

WHERE id != 1

在教义中?

到目前为止我有这个

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

但是我该如何做一个“不等于”呢?

这可能很愚蠢,但我找不到任何参考?

谢谢

【问题讨论】:

    标签: doctrine-orm


    【解决方案1】:

    现在有一种方法可以做到这一点,使用 Doctrine's Criteria。

    可以在How to use a findBy method with comparative criteria 中看到一个完整的例子,但下面是一个简短的答案。

    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);
    

    【讨论】:

    • 在被接受的答案被接受的时候,它是正确的答案:) 几年后情况发生了变化!
    • 我建议更新为:使用 Doctrine\Common\Collections\Criteria; $expr = 标准::expr(); $criteria = Criteria::create();
    • @Jpsy 我没有跟上 Doctrine,有什么理由更喜欢它吗?
    • @ElYobo:Doctrine\Common\Collections\Criteria 被定义为具有静态方法的静态类(参见:doctrine-project.org/api/collections/1.3/…)。所以应该使用CLASS::method() 静态访问它,而不是使用new CLASS() 实例化它。
    • 是的,你是对的。我复制的 sn-p 来自我上面提供的链接,示例代码来自 Doctrine 开发人员之一的 Ocramius,因此可能该 API 在编写后发生了变化。
    【解决方案2】:

    没有内置的方法可以让你做你想做的事情。

    您必须向您的存储库添加一个方法,如下所示:

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

    希望这会有所帮助。

    【讨论】:

    • 我不确定这如何回答这个问题,因为它试图根据值 -1 匹配记录,而不是查询不等于 1 的值
    • 此答案在编写时是正确的,但现在已受支持;在这个问题的其他地方查看我的答案。
    【解决方案3】:

    为了提供更多的灵活性,我会将下一个函数添加到我的存储库中:

    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();
    }
    

    然后,我可以在我的控制器中这样调用它:

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

    【讨论】:

    • 你能告诉我在哪里添加这个方法吗?
    • 在自定义存储库中,与实体相关。在 Symphony 中,要访问使用默认存储库的数据,您可以定义自己的扩展。阅读更多the doctrine docs
    【解决方案4】:

    根据 Luis 的回答,您可以做一些更像默认 findBy 方法的事情。

    首先,创建一个所有实体都将使用的默认存储库类。

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

    或者你可以在 config.yml 中编辑它

    教义: 形式: default_repository_class: MyCompany\Repository

    然后:

    <?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();
        }
    
    }
    

    用法和findBy方法一样,例子:

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

    【讨论】:

      【解决方案5】:

      我很容易解决了这个问题(没有添加方法)所以我会分享:

      use Doctrine\Common\Collections\Criteria;

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

      顺便说一句,我正在使用 Zend Framework 2 中的 Doctrine ORM 模块,我不确定这在任何其他情况下是否兼容。

      在我的例子中,我使用了这样的表单元素配置:在单选按钮数组中显示除“guest”之外的所有角色。

      $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')
                      ),
                  ),
              ),
          ),
      ));
      

      【讨论】:

      • 你就是男人!我找这个已经很久了。您是否在文档中找到了相关内容?
      • 很确定我从浏览源代码中挖掘到了这个细节
      • 谢谢你,我相信其他人也在寻找这个。
      【解决方案6】:

      我使用 QueryBuilder 来获取数据,

      $query=$this->dm->createQueryBuilder('AppBundle:DocumentName')
                   ->field('fieldName')->notEqual(null);
      
      $data=$query->getQuery()->execute();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多