我们正在与许多不同的供应商和客户站点构建一个CMS和网站建设平台,因此有许多不同的内容类型实体,它们是由通用控制器和助手服务编辑的,它们不一定(容易)知道实体管理器对于给定实体是什么。
注意:我们有几个entityManagers来分开访问不同的数据库,例如全局数据库、计费数据库、本地数据库等。
在许多情况下,我们需要检测实体的EntityManager是什么。例如,我们有一个MediaHelper,它动态地将数据库中的媒体与实体上的匹配字段相关联(这不适用于关联,因为媒体必须与任何实体连接,您不能拥有这种动态关联,我们不希望有100个不同的关联)。
媒体在一个由“本地”EntityManager管理的包中。但是该实体可能位于“全局”EntityManager中(您不能假设它位于同一个实体管理器中)。因此,我们需要检测和持久化正确实体管理器的正确实体。
,那么您建议如何动态地检测实体的entityManager?
原始自定义方法
注意:接受的答案是一个更好的解决方案。这只是为了存档目的。。
下面是一个简单的解决方案。但我对Symfony和Doctrine还不太了解,不知道这是不是个坏主意?还有人知道吗?如果不是,我不知道为什么这不会是核心,作为一个理论实用程序。
我创建了一个将Doctrine服务注入其中的EntityHelper服务:
gutensite_cms.entity_helper:
class: Gutensite\CmsBundle\Service\EntityHelper
arguments:
- "@doctrine"然后,在实体助手中有一个简单的函数来获取实体的实体管理器( config.yml已经为实体管理器注册了捆绑包):
/**
* Automagically find the entityManager for an entity.
* @param $entity
* @return mixed
*/
public function getManagerForEntity($entity) {
$className = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity));
foreach (array_keys($this->doctrine->getManagers()) as $name) {
if(in_array($className, $this->doctrine->getManager($name)->getConfiguration()->getMetadataDriverImpl()->getAllClassNames())) return $em;
}
}注意:https://github.com/doctrine/DoctrineBundle/blob/master/Registry.php已经做了一些与这个foreach循环几乎相同的事情,我只是修改了这个想法,返回实体管理器而不是名称空间。
public function getAliasNamespace($alias) {
foreach (array_keys($this->getManagers()) as $name) {
try {
return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias);
} catch (ORMException $e) {
}
}
throw ORMException::unknownEntityNamespace($alias);
}更新10/21/15:根据@Cerad的建议更新实体检测代码。
发布于 2015-10-21 00:07:43
根据@qooplmao的建议,理论核心已经有了一种简单的方法。
// 1) get the real class for the entity with the Doctrine Utility.
$class = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity))
// 2) get the manager for that class.
$entityManager = $this->container->get('doctrine')->getManagerForClass($class);根据Cerad和Qooplmao的建议,更新10/22/15
发布于 2015-10-21 07:28:26
您能不能给实体管理器一个适合它的上下文的别名呢?您谈论的是环球、计费、本地,例如:
'service_manager' => array(
'aliases' => array(
'global_entity_manager' => 'My\Global\EntityManager',
'billing_entity_manager' => 'My\Billing\EntityManager',
'local_entity_manager' => 'My\Local\EntityManager',
),
)还可以将实体管理器映射到实体的命名空间。假设您有一个用于您的全局实体的文件夹,即Global\Entity,那么您可以为这些实体Global\Entity\EntityManager别名实体管理器。该解决方案的优点是可以将多个名称空间映射到同一个实体管理器,因此您的Billing和Global实体可以轻松地共享相同的实体管理器:
'service_manager' => array(
'aliases' => array(
'Global\Entity\EntityManager' => 'My\Global\EntityManager',
'Billing\Entity\EntityManager' => 'My\Global\EntityManager', // <-same name
'Local\Entity\EntityManager' => 'My\Local\EntityManager',
),
)这只有在一个名称空间中的实体是由同一个EntityManager实例管理的情况下才能起作用。我很难相信在任何项目中都不会出现这种情况,但否则你可能应该稍微重组一下?:D。
https://stackoverflow.com/questions/33248792
复制相似问题