Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Doctrine2/将元素从一个集合移动到另一个集合_Php_Symfony_Doctrine Orm_Zend Framework2 - Fatal编程技术网

Php Doctrine2/将元素从一个集合移动到另一个集合

Php Doctrine2/将元素从一个集合移动到另一个集合,php,symfony,doctrine-orm,zend-framework2,Php,Symfony,Doctrine Orm,Zend Framework2,我有3个实体:发票、服务和行 发票包含服务的集合 服务包含行的集合 我想将一个行从服务集合移动到另一个服务集合,但在刷新时,我尝试移动的行元素将从数据库中删除 没有持久/刷新,单元测试正常 用法示例: if ($transferService) { $line->transferToService($service1, $service2); } else { $line->setService($service2); } 发票: class Invoice {

我有3个实体:
发票
服务

  • 发票
    包含
    服务的集合
  • 服务
    包含
    行的集合
我想将一个
服务
集合移动到另一个
服务
集合,但在刷新时,我尝试移动的
元素将从数据库中删除

没有持久/刷新,单元测试正常

用法示例:

if ($transferService)
{
    $line->transferToService($service1, $service2);
}
else
{
    $line->setService($service2);
}
发票:

class Invoice
{
    /**
     * @ORM\OneToMany(targetEntity="Service", mappedBy="invoice", cascade={"persist", "merge", "remove"}, orphanRemoval=true)
     */
    protected $services;

    // ...

    public function __construct()
    {
        $this->services = new ArrayCollection();
    }

    #################################################
    # SERVICES Array Collection handling            #
    #################################################

    public function getServices()
    {
        return $this->services;
    }

    public function setServices($services)
    {
        $this->services = new ArrayCollection();

        return $this->addServices($services);
    }

    public function addService(Service $service)
    {
        if (!$this->services->contains($service))
        {
            $this->services->add($service);
            $service->setInvoice($this);
        }

        return $this;
    }

    public function addServices($services)
    {
        foreach ($services as $service)
        {
            $this->addService($service);
        }

        return $this;
    }

    public function removeService(Service $service)
    {
        if ($this->services->contains($service))
        {
            $this->services->removeElement($service);
        }

        return $this;
    }

    public function removeServices($services)
    {
        foreach ($services as $service)
        {
            $this->removeService($service);
        }

        return $this;
    }        

    // ...
}
服务:

class Service
{
    /**
     * @ORM\OneToMany(targetEntity="Line", mappedBy="service", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
     */
    protected $lines;

    /**
     * @ORM\ManyToOne(targetEntity="Invoice", inversedBy="services", cascade={"persist", "merge"})
     * @ORM\JoinColumn(name="invoice_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $invoice;

    // ...

    public function __construct()
    {
        $this->lines = new ArrayCollection();
    }

    public function getInvoice()
    {
        return $this->invoice;
    }

    public function setInvoice(Invoice $invoice)
    {
        $this->invoice = $invoice;
        $invoice->addService($this);

        return $this;
    }

    #################################################
    # LINES Array Collection handling               #
    #################################################

    public function setLines($lines)
    {
        $this->lines = new ArrayCollection();

        return $this->addLines($lines);
    }

    public function getLines()
    {
        return $this->lines;
    }

    public function addLine(Line $line)
    {
        if (!$this->lines->contains($line))
        {
            $this->lines->add($line);
            $line->setService($this);
        }

        return $this;
    }

    public function addLines($lines)
    {
        foreach ($lines as $line)
        {
            $this->addLine($line);
        }

        return $this;
    }

    public function removeLine(Line $line)
    {
        if ($this->lines->contains($line))
        {
            $this->lines->removeElement($line);
        }

        return $this;
    }

    public function removeLines($lines)
    {
        foreach ($lines as $line)
        {
            $this->removeLine($line);
        }

        return $this;
    }

    // ...
}
行:

class Line
{
    /**
     * @ORM\ManyToOne(targetEntity="Service", inversedBy="lines", cascade={"persist", "merge"})
     * @ORM\JoinColumn(name="service_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $service;

    public function setService(Service $service)
    {
        $this->service = $service;
        $service->addLine($this);

        return $this;
    }

    public function transferToService(Service $serviceFrom, Service $serviceTo)
    {
        $this->setService($serviceTo);
        $serviceFrom->removeLine($this);

        return $this;
    }

    public function getService()
    {
        return $this->service;
    }

    // ...

}

这是由于
删除={true}
造成的。这意味着收集对象仅由“原始”所有者(例如:
Line
)私有。

您的代码似乎工作得很好,除非原始元素消失了,但它们也使用不同的ID重新创建,也许您没有注意到。请检查这种情况,因为我经历过不止一次


因此,如果您想保留相同的对象,您应该删除
孤立删除
,并手动处理收集生命周期(包括删除;我打赌您使用此功能在表单收集和嵌入表单中尽可能少编写代码)

该死,您完全正确!(你猜得对;)“代码越少,bug越少”)。但原始元素并没有被再次创建。谢谢你的帮助answer@ceadreak请注意:如果您的集合的主键与外键约束一起插入到其他表中,此解决方案将不再有效@DonCastillo您有什么建议?@ceadreak如果您有这种情况,请删除孤立项并手动处理元素删除操作Yep,我就是这么做的