Symfony4 - Doctrine Cross Database 加入配置



我需要跨数据库关系,我已经读过这个,但由于映射问题,我无法得到我想要的东西。 这是我的情况

namespace AppEntityUtility;
use DoctrineORMMapping as ORM;
use AppEntityCrmUser;
/**
* Description of Test
*
* @ORMTable(name="fgel_utility.fgel_test")
* @ORMEntity(repositoryClass="AppRepositoryUtilityTestRepository")
*/
class Test
{
/**
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* 
* @var User
* 
* @ORMManyToOne(targetEntity="AppEntityCrmUser")
* @ORMJoinColumn(name="user_cod", referencedColumnName="AUCUT") 
*/
protected $user = null;
public function getId()
{
return $this->id;
}
public function getUser(): User
{
return $this->user;
}
public function setId($id)
{
$this->id = $id;
return $this;
}
public function setUser(User $user)
{
$this->user = $utente;
return $this;
}
}

namespace AppEntityCrm;
use DoctrineORMMapping as ORM;
/**
* 
* @ORMTable(name="crm.USER")
* @ORMEntity(repositoryClass="AppRepositoryFintelGasDatiAnuteRepository")
*/
class User
{
/**
* 
* @ORMId
* @ORMColumn(name="AUCUT", type="integer", nullable=false)
*/
protected $codiceCliente;
# SOME CODE
}

我的学说.yaml

doctrine:
orm:
default_entity_manager: default
entity_managers:
#################################
# Update schema only with this em
#################################
default:
connection: mssql_1
mappings:
Utility:
type:     "annotation"    
# The directory for entity (relative to bundle path)
dir:      '%kernel.project_dir%/src/Entity/Utility'   
prefix:   'AppEntityUtility'
alias: Utility
mssql_crm:
connection: mssql_1
mappings:
Crm:
type: "annotation" 
# The directory for entity (relative to bundle path)
dir: '%kernel.project_dir%/src/Entity/Crm'   
prefix: 'AppEntityCrm'
alias: Crm

所以他们共享相同的连接(但不同的em(。连接的用户具有读取/写入两个数据库的权限(但只能更改fgel_utility数据库的架构。这两个数据库都存储在 SQL Server 2008 中。 当我尝试执行时

php bin/console doctrine:schema:update --dump-sql

我收到此错误

配置的链中找不到类"应用\实体\Crm\用户" 命名空间 App\Entity\Utility, FOS\UserBundle\Model

您实际上可以欺骗 Doctrine 对 MySQL/MariaDB 进行跨数据库连接查询,只需在 ORM\Table 注释中为数据库名称添加前缀:

// src/Entity/User.php
@ORMTable(name="dbname.users")

这将由 Doctrine 在所有 SELECT、JOIN 语句中使用。

也就是说,使用此解决方案,将不会使用来自 DATABASE_URL 的 DB_NAME 或 env 文件的任何其他值,这可能会导致混淆(因为数据库名称应耦合到连接,而不是实体(。

由于您无法解析ORM映射中的动态值,例如"@ORM\Table(name=%env(DBNAME(%.users"(,但这里是如何使用Doctrine中的LoadClassMetadata事件动态完成该工作的示例。

类构造函数将 Entities 命名空间作为第一个参数,将数据库名称作为第二个参数。

当 Doctrine 运行元数据加载时,它将使用每个实体的元数据类触发回调方法,您可以在这些值上动态处理和设置表名。

// src/DatabasePrefixer.php
class DatabasePrefixer implements EventSubscriber
{
private $namespace;
private $tablePrefix;
/**
* @param $namespace string The fully qualified entity namespace to add the prefix
* @param $tablePrefix string The prefix
*/
public function __construct($namespace, $tablePrefix)
{
$this->namespace = $namespace;
$this->tablePrefix = $tablePrefix;
}
public function getSubscribedEvents()
{
return ['loadClassMetadata'];
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
if ($this->namespace == $classMetadata->namespace) {
$classMetadata->setTableName(sprintf('%s.%s', $this->tablePrefix, $classMetadata->table['name']));
}
}
}

假设你有一个DB_NAME env变量,在你的config/services.yml中将类配置为服务,使用Symfony的yaml解析功能,以及事件标记来侦听正确的Doctrine事件:

// config/services.yaml
services:
[...]
dbname.prefixer:
class: AppDatabasePrefixer
arguments:
$namespace:   'AppEntity'
$tablePrefix: '%env(DB_NAME)%'
tags:
- { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }

根据此 https://github.com/doctrine/doctrine2/issues/6350 不支持不同实体管理器(相同连接(之间的跨数据库联接。

相关内容

  • 没有找到相关文章

最新更新