Использование EntityManager внутри сущностей Doctrine 2.0 - PullRequest
33 голосов
/ 05 ноября 2010

У меня есть 2 объекта: Страна (id, имя) и Mapping (id, object, internalId, externalId).Страна и отображение не связаны с ассоциациями (поскольку отображение имеет строки не только для страны).Мне нужно получить внешний идентификатор для страны, используя следующие условия:

  • country.id = mapping.internalId
  • mapping.object = 'country'

Поэтому я планирую добавить функцию getExternalId () в стране

function getExternalId() {
    $em = Registry::getEntityManager();

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
        'object'     => 'country',
        'internalId' => $this->getId()
    ));

    return !empty($mapping) ? $mapping->getExternalId() : false;
}

Вопросы:

  1. Хорошая ли практика - использовать EntityManager внутри сущностей?Если нет, объясните, пожалуйста, как получить внешний идентификатор в моем случае?
  2. Может быть, можно связать страну и сопоставление с помощью файлов yaml?

Заранее спасибо!

Ответы [ 4 ]

51 голосов
/ 05 ноября 2010

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

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

// CountryService
public function getExternalId($country) {}

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

$country->setService($countryService);
$country->getExternalId();

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  
12 голосов
/ 15 июля 2014

Возможно, это не лучшая идея, но есть простой способ сделать это.

Класс UnitOfWork в доктрине будет гидрировать любую сущность, которая реализует ObjectManagerAware, с менеджером сущности и метаданными класса для этой сущности.

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

use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectManagerAware;

/**
 * @ORM\Entity
 */
class MyEntity implements ObjectManagerAware
{
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
    {
        $this->em = $objectManager;
    }
}

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

9 голосов
/ 18 октября 2011

Я думаю, что вам нужно использовать Entity Repositories.Они подробно описаны в документации, хотя найти информацию по ней немного сложно.Вот ссылка на статью Getting Started , в которой описано, как можно создать «хранилище» функций «доступа» для ваших сущностей.

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

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {
1 голос
/ 31 октября 2011

Немного передового дополнения к этому (PHP 5.4 находится в альфа-2 на момент публикации), которое может пригодиться в будущем:

Здесь - некоторые примеры использованияphp 5.4 черты в Doctrine2;одна из которых называется активной сущностью и обеспечивает функциональность стиля активной записи в Doctrine 2, включая доступ к менеджеру сущностей из сущности.

...