在Doctrine 2.0实体中使用EntityManager

Tor*_*llo 33 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;
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 在实体中使用EntityManager是一种好习惯吗?如果不是,请解释如何在我的情况下获得外部身份证?
  2. 也许可以使用yaml文件关联Country和Mapping?

提前致谢!

Bry*_* M. 51

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

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

// CountryService
public function getExternalId($country) {}
Run Code Online (Sandbox Code Playgroud)

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

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

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  
Run Code Online (Sandbox Code Playgroud)

  • 我正在寻找关于教义服务实现的好教程.有人知道好的教程. (6认同)

jua*_*nmf 12

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

UnitOfWorkdoctrine中的类将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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Mik*_*rko 9

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

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

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {
Run Code Online (Sandbox Code Playgroud)