Symfony - соединение базы данных с репозиторием

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

В контроллере диспетчер сущностей нацелен на соединение с базой данных с именем наследие.

Проблема в том, что я не внедрял Entity Manager в свою службу, а только OrderRepository.

Как я могу настроить хорошее соединение БД с репозиторием в моей службе без Entity Manager?

OrderController

// In my Controller
$em = $this->getDoctrine()->getManager('legacy');
$em->persist($order);
$em->flush();

ЗаказатьСервис

// In my Service
public function __construct(OrderRepository $orderRepository)
{
  $this->orderRepository = $orderRepository;
}

public function updateOrderStatus(Order $order)
{
   // some code ...

   $this->orderRepository->save($order);
}

Мне непонятно, о чем вы спрашиваете. Если это репозиторий Doctrine, то сам репозиторий имеет прямой доступ к менеджеру сущностей.

Cerad 24.09.2018 14:52

Привет, @Kevin, могу я спросить, почему вы не хотите, чтобы вводили EntityManager?

Anjana Silva 24.09.2018 15:37

@AnjanaSilva Потому что это плохая практика matthiasnoback.nl/2014/05/…

Kevin 24.09.2018 15:41

@Kevin Я согласен.

Anjana Silva 24.09.2018 17:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
4
326
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны забыть, что вы всегда можете получить диспетчер сущностей в своем репозитории вот так:

$em = $this->getEntityManager();

тогда вы можете использовать его, как обычно, вызывая persist, flush и т. д.

Обратите внимание, что сам класс Repository не зависит от функций уровня доступа к базе данных, таких как вставка или обновление, поэтому он должен вызывать диспетчер сущностей для их выполнения.

да, но я не могу передать имя подключения к базе данных с этим диспетчером сущностей. Но я могу использовать тот, который есть в контроллере: public function getManager($name = null);

Kevin 24.09.2018 15:26

@Kevin - Я подумал, что может быть проблема. У вас есть несколько менеджеров сущностей, верно? Следует понимать, что каждый репозиторий Doctrine создается непосредственно из менеджера сущностей. Репозитории не являются автономными. Вам нужно будет вручную определить определения служб репозитория, чтобы указать, из какого менеджера они создаются. Затем вам нужно будет вручную определить определение службы, чтобы вставить правильный репозиторий. Или вы можете просто внедрить службу доктрины и вытащить из нее менеджер / репозиторий, как это делает контроллер.

Cerad 24.09.2018 15:45

@Cerad Да, у меня несколько Entity Manager. You will need to manually define your repository service definitions to specify which manager they get created from. And then you will need to manually define your service definition to insert the correct repository ... Ммм, я действительно не понимаю, как я могу это сделать.

Kevin 24.09.2018 15:58

Немного поищите «как определить репозитории как службы», пока не найдете пример того, как сделать это с использованием функциональных возможностей контейнера фабрики. В основном вам нужно настроить вызов $ entityManager :: getRepository ($ entityName). Мы немного испорчены, потому что с autowire и базовым классом ServiceRepository нам больше не нужно это делать, когда доступен только один менеджер. Чтобы поддерживать нескольких менеджеров, нужно пойти в старенькую школу.

Cerad 24.09.2018 16:13
Ответ принят как подходящий

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

Вам в основном нужно определять свои службы вручную.

# services.yaml

# assume we have 
# doctrine.orm.default_entity_manager and
# doctrine.orm.legacy_entity_manager 
# already defined through configuration

# define legacy repository
order_repository.legacy:
    class:  Whatever\Repository\OrderRepository
    factory: ['doctrine.orm.legacy_entity_manager', 'getRepository']
    arguments:  
        - 'Whatever\Entity\Order'

# define default repository
order_repository.default:
    class:  Whatever\Repository\OrderRepository
    factory: ['doctrine.orm.default_entity_manager', 'getRepository']
    arguments:  
        - 'Whatever\Entity\Order'

# then your service
Whatever\Service\MyService:
    '@order_repository.legacy'

И тебе должно быть хорошо. Обратите внимание, что ваш репозиторий должен расширять EntityRepository, а не ServiceEntityRepository пакета доктрины.

И если вам кажется, что это слишком много работы, просто введите реестр диспетчера сущностей пакета доктрины и сделайте то, что делает ControllerTrait :: getDoctrine ($ name).

Другие вопросы по теме