【问题标题】:doctrine override default finder methods for all entity学说覆盖所有实体的默认查找器方法
【发布时间】:2019-12-16 01:01:49
【问题描述】:

有一种方法可以覆盖所有实体存储库的默认查找器方法 例如,这是 Doctrine\ORM\EntityRepository 中的默认方法 findBy

 public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
        return $persister->loadAll($criteria, $orderBy, $limit, $offset);
    }    

但我的需求是这样的

 public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
        $criteria['foo'] = 'bar';
        return $persister->loadAll($criteria, $orderBy, $limit, $offset);
    }   

我想通过修改条件数组并在需要时添加一些自定义条件属性来创建一个服务来覆盖此方法。 我知道我可以覆盖每个实体的存储库,但我的项目已经扩大,现在我想要一个实用的解决方案来避免更改所有实体存储库。

【问题讨论】:

  • 你好,为什么不能给这个现有的方法注入海关$criteria
  • 这很恶心 ;) 请改用filters
  • @Weenesta-MathieuDormeval 我有一个大型项目,我想避免在整个项目中为大约三十种方法注入海关标准
  • @emix 和你的回答我刚刚完成了一个使用我的自定义过滤器的监听器,谢谢 :)
  • 很高兴我能帮上忙。请点赞并接受我的回答:)祝你好运。

标签: symfony doctrine-orm doctrine


【解决方案1】:

您可以创建一个扩展 ServiceEntityRepository 的类,并在该类中定义您希望覆盖的所有类。最后,您将需要更新所有存储库以扩展这个新类而不是 ServiceEntityRepository。

【讨论】:

    【解决方案2】:

    参考@emix 的回答这是更详细的解决方案

    现在让我们创建注释。这将被添加到类中,以指示哪些字段将被学说过滤。

    /**
     * @Annotation
     * @Target("CLASS")
     */
    final class CenterSelector
    {
        public $centerFieldName;
    }
    

    并在你的课堂上使用它

     /**
     * @CenterSelector(centerFieldName="you-name-field")
     */
    class CommercialPiece{
       protected $you-name-field;
    }
    

    创建从 SQLFilter 扩展而来的 Filter 类

    class CenterFilter extends SQLFilter
    {
        protected $reader;
    
        public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
        {
    
            if (empty($this->reader)) {
                return '';
            }
    
            // The Doctrine filter is called for any query on any entity
            // Check if the current entity is (marked with an annotation)
            $centerSelector = $this->reader->getClassAnnotation(
                $targetEntity->getReflectionClass(),
                CenterSelector::class
            );
    
            if (!$centerSelector) {
                return '';
            }
    
            // FieldName parameter in annotation
            $fieldName = $centerSelector->centerFieldName;
    
            try {
                $mySelector= $this->getParameter('my-selector');
            } catch (\InvalidArgumentException $e) {
                // No my-selector has been defined
                return '';
            }
    
            if (empty($fieldName) || empty($mySelector)) {
                return '';
            } else{
                var_dump($mySelector);
                // Add the Where clause in the request
                $query = sprintf('%s.%s = %s', $targetTableAlias, $fieldName, $mySelector);
            }
    
            return $query;
        }
    
        public function setAnnotationReader(Reader $reader)
        {
            $this->reader = $reader;
        }
    }
    

    我在 KernelRequest 上创建了一个监听器

      public function __construct(
            ObjectManager $em, 
            SessionInterface $session, 
            Reader $reader)
        {
            $this->em = $em;
            $this->session = $session;
            $this->reader = $reader;
        }
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            $globalSelector = $this->session->get('my-global-selector');           
            $filter = $this->em->getFilters()->enable('center_filter');
            $filter->setParameter('my-selector', $globalSelector );
            $filter->setAnnotationReader($this->reader);
        }
    

    最后别忘了在 config.yml 中添加这个

    orm:
        entity_managers:
            default:
                auto_mapping: true
                filters:
                    center_filter:
                        class: your-name-space\Filter\CenterFilter
                        enabled: true
    

    【讨论】:

      【解决方案3】:

      你不应该这样做。拥抱Doctrine Filters。使用一个,您可以将任何类型的逻辑全局引入所有查询。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-26
        • 2011-04-04
        • 1970-01-01
        • 1970-01-01
        • 2012-01-09
        • 1970-01-01
        • 2018-09-14
        相关资源
        最近更新 更多