使用与多个实体经理的关系

问题描述 投票:0回答:2

我想知道是否可以在驻留在不同数据库中的两个实体之间创建关系。

例如,如果我们采用此处找到的解决方案 http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html 并创建与客户数据库中的用户到默认数据库中的帖子的一对多关系.

这是 Symfony2 和 Doctrine 支持的东西吗?

symfony doctrine-orm
2个回答
53
投票

使用不同的对象管理器(实体管理器)不允许对象图相交。这种情况太复杂了,不受 Doctrine ORM 管理。

如果您需要这种情况,请通过保存相关对象的标识符(旧样式)而不是对它们的引用来保持对象图断开连接,然后通过服务手动获取对象。您可以在Doctrine2 ORM 和 Doctrine2 MongoDB ODM 之间的连接示例中找到一个很好的例子来说明它是如何工作的。或者,您也可以使用

@PostLoad
事件侦听器,通过我在示例中链接的存储库创建链接来填充实体中的数据。
@PostPersist
也是如此(它应该提取相关对象的标识符),但要注意这种技术可能会变得非常混乱。

此外,如果您的 RDBMS 支持在单个主机上进行跨数据库操作,您可以只使用一个 EntityManager 并使用

@ORM\Table(name="schemaname.tablename")
引用另一个表。


0
投票

这是一个非常古老的问题,但它仍然由 Symfony(现在是 6.2)链接,所以我会快速更新它,因为由于它的不精确,我花了大约一个月的时间与两个实体打交道。

我所有问题的解决方案就是这件小事:

#[ORM\Table(schema: 'name_of_database')]

将此属性添加到您的实体中,瞧 - 它现在将在为此实体生成 SQL 查询时使用此数据库名称。但这基本上是对该实体的数据库名称进行硬编码——它不会在不同的环境中改变(例如在测试或不同的设置中)。

为了解决这个问题,我在 Doctrine 事件

loadClassMetadata
中添加了新的监听器,当环境变量更改为
test
:

时,它会更改所选实体的模式
namespace App\EventListener;

use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;

#[AsDoctrineListener(event: Events::loadClassMetadata, priority: 500)]
class DoctrineListener
{
    public function loadClassMetadata(LoadClassMetadataEventArgs $event): void
    {
        if ('test' === ($_ENV['APP_ENV'] ?? false)) {
            $meta = $event->getClassMetadata();
            if (isset($meta->table['schema'])) {
                $meta->table['schema'] .= '_test';
            }
        }
    }
}

有了这个,您还可以拥有动态

schema
- 如果需要,可以根据设置进行更改。希望对您有所帮助。

相关问题
热门问答
最新问题