在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; }
问题:
- 在实体内部使用EntityManager是不是很好的做法? 如果没有,请解释如何获得外部身份证在我的情况?
- 也许有可能使用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理器。