1

我创建了一个只有 2 个实体的 Bundle(称为 MYBUNDLE):菜单和组。两者都被声明为 mappedSuperclass,因为我需要这个包可以用于其他项目。作为一个条件,项目必须从这些类扩展以通过设置表名或添加一些字段来自定义它们。例如:

MYBUNDLE 中的类:

class Group{        
    protected $id;
    protected $menus;
}
class Menu{        
    protected $id;
    protected $groups;
}

YML 用于从 MYBUNDLE 映射我的实体

Project\MYBUNDLE\Entity\Menu:
    type: mappedSuperclass    
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO

Project\MYBUNDLE\Entity\Group:
    type: mappedSuperclass
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    manyToMany:
        menus:
            targetEntity: Menu
            joinTable:
                name: sf_group_menu
                joinColumns:
                    sf_group_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    sf_menu_id:
                        referencedColumnName: id

我的子包中的类:

use Project\MYBUNDLE\Entity\Group as TGroup;
/**
 * @ORM\Entity
 * @ORM\Table(name="sf_group")
 */
class Group extends TGroup
{ }

use Project\MYBUNDLE\Entity\Menu as TMenu;
/**
 * @ORM\Entity
 * @ORM\Table(name="sf_menu")
 */
class Menu extends TMenu
{ }

然而,这两个类中的每一个都有一个属性,可以在它们之间建立多对多关联(由于 mappedSuperclass 不允许反向,我的关联是单向多对多关联)。

我需要在 MYBUNDLE 中进行查询。使用多对多关联连接两个表的查询。我想在 MYBUNDLE 中进行此查询的原因是因为此捆绑包具有一项服务,该服务可以在组或组中绘制菜单。这个方法应该从这个包中得到方便,所以其他包可以使用它,我不必在每个子包中实现。

我的部分解决方案是为我的 MYBUNDLE 制作一个配置部分,例如:

mybundle:
    menu_entity: 
        name: MyprojectChildBundle\Entity\Menu
    group_entity:
        name: MyprojectChildBundle\Entity\Group

通过这个配置,我可以在 MYBUNDLE 中使用子包的存储库,如下所示:

$this->em->getRepository("MyprojectChildBundle:Group")-findAll();

当我在没有连接的情况下进行查询时,一切正常。另一方面,当我这样做时:

$repo = $this->em->getRepository("MyprojectChildBundle:Group");
$result = $repo->createQueryBuilder("c")          
               ->select('c, d')
               ->join("c.menus", "d")->getQuery()->getResult();


return $result

一切都失败了,因为形成的 SQL 试图寻找一个不存在的名为“Menu”的表,因为它被称为“sf_menu”。表组正确更改为“sf_group”,因为我正在使用我孩子的存储库。但是,使用此存储库只需更改该类的名称,而不是连接表的名称。

我怎样才能在 MYBUNDLE 中进行这种查询?非常感谢。

4

1 回答 1

1

最后我找到了解决方案:)

我必须再创建 2 个类作为我的模型。这些类应该具有所有映射数据库,并且应该像这样声明为单继承:

#src\Myproject\MYBUNDLE\Model\Menu

/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"menu1" = "Myproject\MYBUNDLE\Entity\Menu", "menu2" = "Menu"})
 */
abstract class Menu {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    // Other fields
}

您应该对这两个实体(菜单和组)执行此操作。这种实现的优点是您不会像以前那样丢失任何关联,因为将它们声明为 mappedSuperClasss。

然后你应该为每个模型类声明一个实体,并将它们声明为 MappedSuperClass。它们应该如下所示:

#src\Myproject\MYBUNDLE\Entity\Menu

use Doctrine\ORM\Mapping as ORM;
use Tixpro\TMenuBundle\Model\Menu as BaseMenu;

/** @ORM\MappedSuperclass */
class Menu extends BaseMenu
{
}

使用此实现,您可以确保不会丢失任何关联。此外,任何实体都可以从您的实体类扩展以添加更多字段并自定义它们。例如:

#src\Project\ChildBundle\Entity\Menu

use Myproject\MYBUNDLE\Entity\Menu as TMenu;
/**
 * @ORM\Entity
 * @ORM\Table(name="sf_menu")
 */

class Menu extends TMenu{
    //put your code here
}

不要忘记配置 config.yml 中的参数以使用 MYBUNDLE。

mybundle:
    menu_entity: 
        name: MyprojectChildBundle\Entity\Menu
    group_entity:
        name: MyprojectChildBundle\Entity\Group

如果您不这样做,您将无法知道 MYBUNDLE 中的存储库,因此您无法在您的 MYBUNDLE 中进行联合查询。

最后,在设置参数并实现之后,您可以在 MYBUNDLE 中使用连接查询,如下所示:

$repo = $this->em->getRepository("MyprojectChildBundle:Menu");
$result = $repo->createQueryBuilder("wa")          
    ->select('wa, da')
    ->join("wa.roles", "da")

就这样。

于 2013-05-07T00:24:50.853 回答