在Doctrine 2.0实体中使用EntityManager

时间:2010-11-05 17:13:45

标签: entitymanager doctrine-orm

我有2个实体:Country(id,name)和Mapping(id,object,internalId,externalId)。 国家和地图未与关联相关联(因为“映射”不仅包含国家/地区的行)。我需要使用以下条件获取国家/地区的外部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是一种好习惯吗?如果不是,请解释如何在我的案例中获得外部身份证明?
  2. 也许可以使用yaml文件关联Country和Mapping?
  3. 提前致谢!

4 个答案:

答案 0 :(得分:51)

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

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

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

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

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

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  

答案 1 :(得分:12)

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

doctrine中的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方法。

答案 2 :(得分:9)

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

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

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {

答案 3 :(得分:1)

这是一个略微前沿的补充(PHP 5.4在本帖时为alpha 2),可能在将来使用:

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