如何删除具有两个关系的“反面实体”

时间:2019-04-06 15:43:20

标签: php symfony doctrine-orm associations

销售,库存和目录之间存在双向关系。 销售和库存应该有一个目录条目。但是这个 目前并非总是如此。因此关系是“可空的”。

for

所有这些都是在Symfony中使用make:entity自动生成的。组织时 目录,也需要删除目录条目。

String input = "A,B,C,D,E";
StringBuilder op = new StringBuilder();
int idx = 0;
int idxUpto = 0;
do {
    idxUpto = input.indexOf(",", idx);
    if (idxUpto == -1) {
        String term = input.substring(idx, input.length());
        op.append(term);
        System.out.println(term);
        System.out.println("There is no more commas in String");
        break;
    }
    String term = input.substring(idx, idxUpto);
    op.append(term);
    idx = idxUpto+1;
    System.out.println(term);
} while(true);

A
B
C
D
E
There is no more commas in String

到目前为止非常简单。但是我如何删除关联而不删除 任何股票或销售?我确实收到了这样的错误(没有删除关联)

class Sale {

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Stock", inversedBy="sales")
     */
    private $stock;

    public function getCatalog(): ?Catalog
    {
        return $this->catalog;
    }

    public function setCatalog(?Catalog $catalog): self
    {
        $this->catalog = $catalog;

        return $this;
    }
}

class Stock
{
    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Catalog", inversedBy="stock")
     */
    private $catalog;

    public function getCatalog(): ?Catalog
    {
        return $this->catalog;
    }

    public function setCatalog(?Catalog $catalog): self
    {
        $this->catalog = $catalog;

        return $this;
    }
}

class Catalog
{
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Sale", mappedBy="catalog")
     */
    private $sales;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Stock", mappedBy="catalog")
     */
    private $stock;

    public function addSale(Sale $sale): self
    {
        if (!$this->sales->contains($sale)) {
            $this->sales[] = $sale;
            $sale->setCatalog($this);
        }

        return $this;
    }

    public function removeSale(Sale $sale): self
    {
        if ($this->sales->contains($sale)) {
            $this->sales->removeElement($sale);
            // set the owning side to null (unless already changed)
            if ($sale->getCatalog() === $this) {
                $sale->setCatalog(null);
            }
        }

        return $this;
    }

    public function getStock(): ?Stock
    {
        return $this->stock;
    }

    public function setStock(?Stock $stock): self
    {
        $this->stock = $stock;

        // set (or unset) the owning side of the relation if necessary
        $newCatalog = $stock === null ? null : $this;
        if ($newCatalog !== $stock->getCatalog()) {
            $stock->setCatalog($newCatalog);
        }

        return $this;
    }
}

或类似

class CatalogController extends AbstractController 
{

    /**
     * @Route(
     *     path    = "/catalog-delete/{id<[1-9]\d*>}",
     *     name    = "catalog_delete",
     *     methods = {"GET"}
     * )
     */
    public function delete(int $id)
    {
        // get catalog
        $catalog = $this->catalogRepository->find($id);
        if (!$catalog) {
            throw $this->createNotFoundException($this->translator->trans('system.error.notfound') . $id);
        }

        // delete
        $this->entityManager->remove($catalog);
        $this->entityManager->flush();

        return $this->redirectToRoute('catalog_list');
    }
}

当我尝试在函数内部delete();)

Cannot delete or update a parent row: a foreign key constraint fails (`symfony`.`sale`, CONSTRAINT `FK_E54BC005DCD6110` FOREIGN KEY (`stock_id`) REFERENCES `stock` (`id`))

我可以使用DQL在其中设置category_id 销售和库存为空(更新销售/库存SET类别ID =空,而类别ID = X)。 但是我认为这不是常见的“ orm方式”。

在这种情况下,自动生成的功能对我来说有点不足 也是这里的学说文档 https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-associations.html#removing-associations

我已经读到,只有所有权方才负责关联, 但是如何获得库存和所有销售的功能(如果有的话)?

很抱歉,还有一个很长的问题和一个基本主题。

感谢您和最诚挚的问候


我的问题被标记为重复。主要区别是

我想在我的问题中知道如何实现将拥有的实体(两个或多个)设置为null的函数调用。删除过程。哪个实体,什么样的电话。仅添加

Call to a member function getCatalog() on null

(旧答案)不能解决问题。

--------- DQL解决方案 ----------

$catalog->setStock(null);
foreach($catalog->getSales() as $sale) {
    $catalog->getSales()->removeElement($sale); // ????????
}

我最长的帖子;)

1 个答案:

答案 0 :(得分:0)

解决方案的确是这种简单的设置。也可以是单向关系。

class Sale {

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Stock")
     * @ORM\JoinColumn(onDelete="SET NULL")
     */
    private $stock;

    public function getCatalog(): ?Catalog
    {
        return $this->catalog;
    }

    public function setCatalog(?Catalog $catalog): self
    {
        $this->catalog = $catalog;

        return $this;
    }
}

class Stock
{
    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Catalog")
     * @ORM\JoinColumn(onDelete="SET NULL")
     */
    private $catalog;

    public function getCatalog(): ?Catalog
    {
        return $this->catalog;
    }

    public function setCatalog(?Catalog $catalog): self
    {
        $this->catalog = $catalog;

        return $this;
    }
}

class Catalog
{

}

然后,控制器功能运行良好。昨天我尝试了太多东西...