我创建了一个只有2个实体的Bundle(名为MYBUNDLE):Menu和Group。两者都被声明为mappedSuperclass,因为我需要这个bundle可以用于其他项目。作为条件,项目必须从这些类扩展,以通过设置表名或添加一些字段来自定义它们。例如:
进入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内部进行查询。将两个表与manytomany关联连接的查询。 我想在MYBUNDLE中进行此查询的原因是因为此捆绑包具有一个服务,该服务在组或组中绘制菜单deppending。这个方法应该方便这个包,所以其他包可以使用它,我不必在每个子包中实现。
我的部分解决方案是为我的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中进行此类查询?非常感谢。
答案 0 :(得分: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中配置params以使用MYBUNDLE。
mybundle:
menu_entity:
name: MyprojectChildBundle\Entity\Menu
group_entity:
name: MyprojectChildBundle\Entity\Group
如果你不这样做,你就无法知道MYBUNDLE中的存储库,因此你无法在你的MYBUNDLE中加入查询。
最后,在设置了params并进行实现后,您可以在MYBUNDLE中使用联接查询,如下所示:
$repo = $this->em->getRepository("MyprojectChildBundle:Menu");
$result = $repo->createQueryBuilder("wa")
->select('wa, da')
->join("wa.roles", "da")
就是这样。