在Symfony2中使用同一个包中的两个实体管理器

时间:2012-02-16 12:44:56

标签: php doctrine symfony entity bundle

我尝试与同一个捆绑的两个实体经理一起工作。我的配置是这样的:

orm:

    default_entity_manager:   default
    entity_managers:
        electra:
            connection:       electra
            mappings:
                XXDemoBundle: ~
        default:
            connection:       default
            mappings:
                XXDemoBundle: ~

有没有办法告诉哪个entites属于哪个实体经理?如果我想使用一个不属于默认实体管理器的表,它现在崩溃了。

由于

  • 更新

这是我的连接配置:

doctrine:
    dbal:
        default_connection:       default
        connections:
            default:
                dbname:           old_project
                user:             root
                password:         123123
                host:             1.1.1.1
                port:             1
            electra:
                dbname:           electra
                user:             root
                password:         123123
                host:             2.2.2.2
                port:             2

orm:
    default_entity_manager:   electra
    entity_managers:
        electra:
            connection:       electra
            mappings:
                XXDemoBundle: ~


        default:
            connection:       default
            mappings:
                XXDemoBundle: ~

2 个答案:

答案 0 :(得分:22)

要在同一个捆绑包中使用多个entitymanager,您必须为每个实体管理器配置映射选项。

http://symfony.com/doc/current/reference/configuration/doctrine.html

禁用配置文件

doctrine:
    dbal:
        default_connection:   default
        connections:
            default:
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name%
                user:     %database_user%
                password: %database_password%
                charset:  UTF8
            second:
                driver:   %database_sqlite_driver%
                host:     ~
                port:     ~
                dbname:   %database_sqlite_shop_name%
                path:     %database_sqlite_shop_name%
                user:     ~
                password: ~
                charset:  UTF8

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        default_entity_manager:   default
        entity_managers:
            default:
                connection:       default
                mappings:
                    YourBundle:
                      # you must specify the type
                      type:     "annotation"    
                      # The directory for entity (relative to bundle path)
                      dir:      "Entity/FirstDb"        
                      #the prefix 
                      prefix:   "Your\Bundle\Entity\FirstDb" 
            shop:
                connection:       second
                mappings:
                    YourBundle:
                      type: "annotation"
                      #here the second path where entity for the connection stand
                      dir: "Entity/SecondDb" 
                      #the prefix
                      prefix: "Your\Bundle\Entity\SecondDb" 

您现在可以使用控制台通过--em参数

管理数据库

Ex:更新商店实体管理员数据库

php app/console doctrine:schema:update --em=shop

从Your \ Bundle \ Entity \ SecondDb

中读取映射信息

Ex:更新默认实体管理器的数据库

php app/console doctrine:schema:update   

从Your \ Bundle \ Entity \ FirstDb

中读取映射信息

答案 1 :(得分:2)

确定。试图编辑您的原始帖子,但它正在等待同行评审。不知道需要多长时间。尝试将配置更改为:

doctrine:
    dbal:
        default_connection:       default
        connections:

        default:
            dbname:           old_project
            user:             root
            password:         123123
            host:             1.1.1.1
            port:             1

        # Make an explicit connection just for clarity
        old_project:
            dbname:           old_project
            user:             root
            password:         123123
            host:             1.1.1.1
            port:             1            

        electra:
            dbname:           electra
            user:             root
            password:         123123
            host:             2.2.2.2
            port:             2

    orm:
        # Humor me and add these
        auto_generate_proxy_classes: %kernel.debug%
    #   auto_mapping: true

    default_entity_manager:   electra
    entity_managers:

    # Make an explicit old_project em so default does not confuse us
    old_project:
        connection:       old_project
        mappings:
            XXDemoBundle: ~

    electra:
        connection:       electra
        mappings:
            XXDemoBundle: ~


    default:
        connection:       default
        mappings:
            XXDemoBundle: ~

现在完全吹走你的缓存只是为了确保然后运行:

php app/console doctrine:mapping:info --em electra
php app/console doctrine:mapping:info --em old_project

你应该得到相同的结果。我在我的系统上对此进行了测试,所以我很确定如果你不这样做,那么你会在某个地方出现错字。

因此,映射信息正在运行。下一步是验证两个数据库是否与您的实体架构匹配。所以这样做:

php app/console doctrine:schema:update --em electra --dump-sql
php app/console doctrine:schema:update --em old_project --dump-sql

两者都不应该产生任何输出。如果有,那么这意味着您的数据库与您的实体不匹配,并且需要在查询起作用之前解析(可能使用--force选项)。

一旦数据库同步,你应该使用doctrine:query:dql并对两个管理器进行测试查询。然后回到你的代码中。

=========================================

现在已经理解,真正的目标是让两个实体管理器指向同一组实体,但不知何故表明每个实体管理器应将自己限制在这些实体的某组中。这不是S2支持开箱即用的东西。

你可以浏览一下Doctrine手册,看看它如何处理实体元数据,也许可以做些什么,但这可能会变得复杂。

S2真正提供的唯一功能是能够使用mapping属性将实体管理器绑定到一个或多个包中的所有实体。如果你想分享来自一个捆绑包中的七个实体中的三个与另一个捆绑包,那么你只需在第二个捆绑包中重新创建这些实体。可能通过扩展类来避免代码重复。

我想你可能想稍微改变一下你的方法。如果您有一组与多个bundle共享的核心实体,那么将它们放在自己的bundle中。然后,每个后续捆绑包都可以添加其他实体。