我有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;
}
问题:
提前致谢!
答案 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中提供活动记录样式功能,包括从实体内部访问实体管理器。