33

我有 2 个实体:国家(id、名称)和映射(id、对象、internalId、externalId)。Country 和 Mapping 没有关联(因为 Mapping 不仅有国家的行)。我需要使用以下条件获取国家/地区的外部 ID:

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

所以我计划在 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 是一种好习惯吗?如果不是,请解释在我的情况下如何获取外部 ID?
  2. 也许可以使用 yaml 文件将 Country 和 Mapping 关联起来?

提前致谢!

4

4 回答 4

52

允许实体对象依赖实体管理器并不是一个好主意。它将实体与持久层联系起来,这是 Doctrine 2 专门试图解决的问题。依赖实体管理器的最大麻烦是它使您的模型很难在远离数据库的情况下单独测试。

您可能应该依赖服务对象来处理依赖于实体管理器的操作。

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

此外,您可以在模型上创建代理方法来调用外部设置的服务对象。与实体管理器相比,服务对象在测试时更容易模拟。

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

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  
于 2010-11-05T19:47:37.330 回答
13

这可能不是最好的主意,但有一种简单的方法可以做到这一点。

学说中的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;
    }
}

如果您创建一个新实体而不是从数据库中查询它,您将需要手动设置实体管理器,例如使用 setter 方法。

于 2014-07-15T19:11:43.700 回答
9

我认为您需要使用的是实体存储库。这些在文档中有详细说明,尽管很难找到相关信息。这是入门文章的链接,该文章记录了如何为您的实体创建“访问”功能的“存储库”。

此外,这里有一些伪代码可以帮助您入门:

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {
于 2011-10-18T19:17:40.163 回答
1

对此的稍微前沿的附录(在本文发表时 PHP 5.4 处于 alpha 2),将来可能会用到:

以下是在 Doctrine2 中使用 php 5.4 特征的一些示例;其中之一称为活动实体,并在 Doctrine 2 中提供活动记录样式功能,包括从实体内访问实体管理器。

于 2011-10-31T18:35:42.920 回答