在Doctrine 2.0实体中使用EntityManager

我有2个实体:国家(id,名称)和映射(ID,对象,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?

提前致谢!

允许实体对象依赖实体pipe理器并不是一个好主意。 它将实体与持久层连接起来,这是第二条专门要解决的问题。 依赖实体pipe理器最大的麻烦在于,它使得你的模型很难孤立地进行testing,远离数据库。

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

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

另外,您可以在您的模型上创build代理方法,以调用外部设置的服务对象。 服务对象比实体pipe理器更容易模拟。

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

这可能不是最好的想法,但有一个简单的方法来做到这一点。

doctrine中的UnitOfWork类将为任何实现ObjectManagerAware的实体提供实体pipe理器和该实体的类元数据。

您只需要实体pipe理器就可以实现如下例所示的界面:

 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; } } 

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

我认为你需要使用的是实体存储库。 这些在文档中详细说明,尽pipe有点难以find信息。 这里是“ 入门指南”文章的链接,其中介绍了如何为您的实体创build“访问”function的“存储库”。

另外这里是一些伪代码,让你开始:

 <?php // repositories/CountryRepository.php use Doctrine\ORM\EntityRepository; class CountryRepository extends EntityRepository { public function getExternalId() { 

这是一个稍微尖端的附录(在这篇文章中,PHP5.4处于alpha2),这在未来可能会有用:

以下是在Doctrine2中使用php 5.4特性的一些例子; 其中一个被称为活动实体,并在Doctrine 2中提供了主动logging样式function,包括从实体内部访问实体pipe理器。