Учение о множестве хранилищ для одной и той же сущности - PullRequest
4 голосов
/ 08 марта 2012

возможно ли иметь два репозитория для одной и той же сущности?

Я пытаюсь что-то подобное, но это не работает ..

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

Есть идеи?

Ответы [ 3 ]

5 голосов
/ 12 марта 2012

Во-первых, зачем вам это делать?

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

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

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

1 голос
/ 12 апреля 2017

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

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

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

1 голос
/ 04 марта 2016

Я нашел решение. Что-то в 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.

...