繁体   English   中英

在Zend框架2中具有MappedSuperclass的Doctrine 2多对多

[英]Doctrine 2 many-to-many with MappedSuperclass in Zend framework 2

我是Doctrine2的新手,正在尝试为以下数据库结构创建实体: 在此处输入图片说明

我想将所有机器零件作为数组放在机器类的一个属性中。 我尝试了这个:

class Machine {
    ....
    /**
     * @var array
     * @ORM\OneToMany(targetEntity="MachineHasPart", mappedBy="machine", cascade={"persist", "remove"}, orphanRemoval=TRUE)
     */
    private $parts;
    ....

    public function getParts () {
        return array_map(
            function ($machineHasPart) {
                return $machineHasPart->getPart();
            },
            $this->parts->toArray()
        );
    }
}

其中MachineHasPart是中间实体/表(例如machineHasCylinder等)的@MappedSuperclass ,但失败并显示:

执行'SELECT FROM machineHasPart t0'时发生异常

我应该在这里重组数据库以使用ORM吗? 还是我的情况有解决方案?

您不能查询@MappedSuperClass 在第6.1Doctrine2文档中也提到了这一点 映射的超类

映射的超类不能是实体,它不可查询且不可持久

这意味着您必须将目标实体更改为可查询的内容,或者必须将MachineHasPart更改为实体并更改为单表继承

当我查看您的数据库结构时,建议将您的Machine实体更改为对零件具有三个独立的关系。 一种用于皮带,一种用于气缸,一种用于齿轮。

然后,而不是一个普通getParts你将有三种方法getBeltsgetCylindersgetGears

如果这确实不是您想要的,那么您可以发表评论。

更新

您也可以使用类继承来解决它。 首先,创建一个也是实体的基类Part ,并在BeltCylinderGear的其他类中使用它:

部分:

<?php

namespace Machine\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Part
 *
 * @ORM\Entity
 * @ORM\Table("part")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discriminator", type="string")
 * @ORM\DiscriminatorMap({
 *     "part" = "Part",
 *     "gear" = "Gear",
 *     "cylinder" = "Cylinder",
 *     "belt" = "Belt",
 * })
 * @property int $id
 */
class Part
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var Machine
     * @ORM\ManyToOne(targetEntity="Machine\Entity\Machine", inversedBy="parts")
     * @ORM\JoinColumn(name="machine_id", referencedColumnName="id", nullable=true)
     */
    protected $machine;

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set id.
     *
     * @param int $id
     * @return self
     */
    public function setId($id)
    {
        $this->id = $id;

        return  $this;
    }

    //... add setters and getters for machine as normal ...
}

在其他部分扩展此类:

带:

<?php

namespace Machine\Entity;

/**
 * Belt
 *
 * @ORM\Entity
 */
class Belt extends Part
{
}

圆筒:

<?php

namespace Machine\Entity;

/**
 * Cylinder
 *
 * @ORM\Entity
 */
class Cylinder extends Part
{

}

齿轮:

<?php

namespace Machine\Entity;

/**
 * Gear
 *
 * @ORM\Entity
 */
class Gear extends Part
{

}

现在,您的机器中涉及的零件如下。

机:

<?php

namespace Machine\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Machine
 *
 * @ORM\Entity
 * @ORM\Table("machine")
 * @property int $id
 */
class Machine
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set id.
     *
     * @param int $id
     * @return self
     */
    public function setId($id)
    {
        $this->id = $id;

        return  $this;
    }

    /**
     * @var Collection
     * @ORM\OneToMany(targetEntity="Machine\Entity\Part", mappedBy="machine")
     */
    protected $parts;

    public function __constuct()
    {
        $parts = new ArrayCollection();
    }

    /**
     *
     * @return Collection
     */
    public function getParts()
    {
        return $this->parts;
    }

    //... add setters and getters for parts as normal ...
}

在其他部分扩展此类:

在6.1章Doctrine2文档中进一步阅读 映射的超类 (由@Wilt引用):

...此外,仅当映射的超类目前仅在一个实体中使用时,才可能有多对多关联...

这意味着在这种情况下,ORM映射无济于事。 我无法通过MappedSupper类同时收集所有三个实体MachineHasCylinder,MachineHasBelt和MachineHasGear的数据。 我认为使用DQL或本机SQL是解决此问题的唯一方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM