Возможно ли иметь два репозитория для одного и того же объекта?

Пробую что-то подобное, но не получается ..

class PackageRepository extends EntityRepository
{
    public function __construct($em, Mapping\ClassMetadata $class)
    {
        $cmf = $em->getMetadataFactory();
        $class = $cmf->getMetadataFor('Product');
        parent::__construct($em, $class);
    }
}

Любые идеи ?

4
Charles 8 Мар 2012 в 15:14

3 ответа

Лучший ответ

Прежде всего, зачем вам это нужно?

Во-вторых, чтобы ответить на ваш вопрос. Вы можете иметь сколько угодно репозиториев, работающих с одними и теми же объектами, в конце концов, это всего лишь простые классы.

Но вы можете связать только один класс с классом сущности, используя аннотацию @Repository (или YAML, или XML, что угодно). Все данные сопоставления хранятся в EntityManager. EntityManager будет знать, что только один класс репозитория связан с классом сущности, если вы попытаетесь получить его с помощью $entity->getReposiotry() или подобного, он вернет только связанный класс.

Но ничто не может помешать вам создать свои собственные классы, которые выполняют некоторые запросы и вызывают их напрямую, явно, не полагаясь на сопоставление репозитория EntityManager.

5
ZolaKt 12 Мар 2012 в 15:19

Я также столкнулся с той же проблемой, когда два пакета Symfony работают с одним и тем же объектом, но запросы разные для каждого пакета, поэтому я также решил создать отдельный репозиторий для каждого пакета. Для Доктрины 2 решением может быть следующее:

  1. "@Repository annotation" может использоваться для указания репозитория по умолчанию или просто избегать его.
  2. Создайте обычный класс репозитория, например «MyEntityRepository».
  3. В коде:

    $myEntityRepo = new MyEntityRepository($entityManager, $entityManager->getClassMetadata('AppBundle:MyEntity'));

2
Molarro 12 Апр 2017 в 16:41

Я нашел решение. Что-то в PHP под названием Trait.

Примере:

class UserRepository extends EntityRepository {

   public function adminQuery1();
   public function adminQuery2();
   public function adminQuery3();
   public function adminQuery4();
   public function adminQuery5();
   public function adminQuery6();    

   public function frontEndQuery1();
   public function frontEndQuery2(); 
   public function frontEndQuery3(); 
   public function frontEndQuery4(); 
   public function frontEndQuery5(); 
   public function frontEndQuery6();     
}

Теперь продолжайте работать с различными частями запроса, и ваш репозиторий быстро станет запутанным и слишком длинным. Ты мог бы

  1. Создать несколько репозиториев, которые наследуют друг друга ИЛИ
  2. Используйте черты характера

Пример ниже:

Trait AdminQuery {
   public function adminQuery1();
   public function adminQuery2();
   public function adminQuery3();
   public function adminQuery4();
   public function adminQuery5();
   public function adminQuery6();    
}

Trait FrontEndQuery {
   public function adminQuery1();
   public function adminQuery2();
   public function adminQuery3();
   public function adminQuery4();
   public function adminQuery5();
   public function adminQuery6();    
}

Фактический класс репозитория.

class UserRepository extends EntityRepository {
   use AdminQuery;
   use FrontEndQuery;      
}

Прелесть этого заключается в том, что ключевое слово this будет относиться к контексту, в котором использовался Trait, что означает, что у вас есть доступ ко всем функциям EntityRepository

Наконец-то нашел вариант использования для Trait.

1
delmalki 4 Мар 2016 в 00:38