【问题标题】:How do I use the cascade option in Symfony2 Doctrine?如何在 Symfony2 Doctrine 中使用级联选项?
【发布时间】:2012-11-14 05:48:35
【问题描述】:

我正在尝试理解 Symfony2Doctrine 中的 cascade 选项。

我希望能够删除子实体(并且不会触发外键约束错误。)

我有 3 个实体:

举报

/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report")
*/
protected $responses;

/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report")
*/
protected $sms;

回应

/**
 * @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
 */
protected $report;

短信

/**
 * @ORM\ManyToOne(targetEntity="Report")
 */
protected $report;

现在我想删除 Response 实体,但我得到了

SQLSTATE[23000]:违反完整性约束:1451 无法删除或更新父行:
外键约束失败 (mybundle.sms, CONSTRAINT FK_B0A93A77BB333E0D FOREIGN KEY (reportId) REFERENCES report (id))

我在哪里使用cascade 选项以及我应该使用哪个选项(detachremove)?

我可以做很多试验和错误来解决这个问题,但我希望得到专家的解释,所以我不会忽略一些事情。

【问题讨论】:

    标签: doctrine cascade


    【解决方案1】:

    尝试使用

    /**
     * @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
     * @ORM\JoinColumn(name="reportId", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $report;
    

    然后更新你的架构。它将添加数据库级级联

    【讨论】:

    • 哟.. 成功了!谢谢。不过,我想我很快就需要重新审视这个问题。我还想删除报告..我会在一分钟内解决..
    • Easy answer Ziumin,竖起大拇指,但我想这会从父母中删除所有孩子?有没有办法留住这些孩子?例如:我想删除一个用户(父母),但保留他的博文(孩子)。然后让博文的作者为空或未知之类的......
    • 试试onDelete="SET NULL"
    【解决方案2】:

    Ziumin 的回答

    ORM JoinColumn 使用onDelete 选项

    当您想要删除子项 (Owning Side) 时该方法有效。

    但是,如果您想删除作为父项 (Inverse Side) 的 Response,此时 cascade 就派上用场了。在Report 实体中,我为其每个集合(OneToMany 关系)添加了以下内容:

    举报

    /**
    * @ORM\OneToMany(targetEntity="Response", mappedBy="report", cascade={"remove"})
    */
    protected $responses;
    
    /**
    * @ORM\OneToMany(targetEntity="SMS", mappedBy="report", cascade={"remove"})
    */
    protected $sms;
    

    现在,当我删除 Report 时,它会删除 ResponseSMS 表中的所有关联条目。

    【讨论】:

      【解决方案3】:

      您也可以使用cascade=all 更新所有操作。

      举报

       /**
       * @ORM\OneToMany(targetEntity="Response", mappedBy="report", cascade={"all"})
       */
      protected $responses;
      
       /**
       * @ORM\OneToMany(targetEntity="SMS", mappedBy="report", cascade={"all"})
       */
      protected $sms;
      

      【讨论】:

      • " 不要盲目地将 cascade=all 应用于所有关联,因为它会不必要地降低应用程序的性能。对于每个被激活的级联操作,Doctrine 也会将该操作应用于关联,无论是单一的还是收藏价值。” -> doctrine-orm.readthedocs.org/en/latest/reference/…
      猜你喜欢
      • 1970-01-01
      • 2015-01-19
      • 2012-02-23
      • 2011-11-23
      • 1970-01-01
      • 2011-12-31
      • 2013-12-31
      • 2012-03-17
      • 1970-01-01
      相关资源
      最近更新 更多