Doctrine orm 使用循环外键删除

Doctrine orm 使用循环外键删除,doctrine-orm,Doctrine Orm,我有两个相互引用的实体:一个是页面实体,它引用了defaultUrl,另一个是Url实体,它引用了页面 这是周期性的,所以一旦我添加了一个相互引用的页面和url,我就不能删除它们 我可以看到两种方法来解决它,但不确定“学说”的方法 使其中一个关系仅成为索引,而不是外键约束 删除时,禁用外键约束检查 我不知道怎么做这两件事。。。你知道吗 谢谢 经验法则,在生成外键时,始终使一个外键可为空或省略一个外键定义 这允许循环中断 最简单的情况(SQL语法,但sampe原则适用): 可以按如下方式断开循环:

我有两个相互引用的实体:一个是
页面
实体,它引用了
defaultUrl
,另一个是
Url
实体,它引用了
页面

这是周期性的,所以一旦我添加了一个相互引用的页面和url,我就不能删除它们

我可以看到两种方法来解决它,但不确定“学说”的方法

  • 使其中一个关系仅成为索引,而不是外键约束
  • 删除时,禁用外键约束检查
  • 我不知道怎么做这两件事。。。你知道吗


    谢谢

    经验法则,在生成外键时,始终使一个外键可为空或省略一个外键定义

    这允许循环中断

    最简单的情况(SQL语法,但sampe原则适用):

    可以按如下方式断开循环:

    CREATE TABLE Employee (
        EmployeeId INTEGER NOT NULL IDENTITY(1,1)
        ManagerId INTEGER NOT NULL
        --...
        PRIMARY KEY EmployeeId NONCLUSTERED
    )
    
    CREATE TABLE Employee (
        EmployeeId INTEGER NOT NULL IDENTITY(1,1)
        ManagerId INTEGER NULL
        --...
        PRIMARY KEY EmployeeId NONCLUSTERED
        FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId)
    )
    
    或如下:

    CREATE TABLE Employee (
        EmployeeId INTEGER NOT NULL IDENTITY(1,1)
        ManagerId INTEGER NOT NULL
        --...
        PRIMARY KEY EmployeeId NONCLUSTERED
    )
    
    CREATE TABLE Employee (
        EmployeeId INTEGER NOT NULL IDENTITY(1,1)
        ManagerId INTEGER NULL
        --...
        PRIMARY KEY EmployeeId NONCLUSTERED
        FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId)
    )
    
    我更喜欢在声明外键时始终跟踪图表并确保没有循环。我将省略最危险的钥匙,直到所有的循环都被打破。这确保了所有表都可以批量导出,然后批量导入到另一个数据库中


    编辑:我发现当你问图书专家这个问题时,你会得到一个答案,比如在删除时关闭外键。这是错误的,原因有二。首先,正常的事务操作不应该改变模式定义。第二,代码的其余部分期望外键在那里,因此不会在应用程序代码中处理它;然而,模式修改有一个令人讨厌的习惯,即在事务中出血或锁定整个表。

    以下是设置此模式的方法。正如前面提到的,您需要将至少一个外键设置为可空

    还考虑设置OnDelet级联设置空值。这将使删除过程更加简单——您不必在删除记录之前将密钥更新为NULL

    您的schema.yml可能如下所示:

    Url:
      columns:
        page_id: { type: integer, notnull: true }
      relations:
        Page: { local: page_id, foreign: id }
    
    Page:
      columns:
        default_url_id: { type: integer, notnull: false }  # ALLOWS NULL foreign key here
      relations:
        DefaultUrl: { class: Url, local: default_url_id, foreign: id, onDelete: SET NULL }
    

    谢谢你,约书亚。我完全明白你的意思。。。然而,你知道在条令中是如何做到这一点的吗?条令不会让你“忘记”声明外键吗?是的,我完全同意你的编辑声明。我宁愿通过“忘记”外键来解决问题。。。我只是在任何地方都找不到关于这个的任何文档,也弄不明白。哦,好吧,我现在就不谈这个了。谢谢砰!这很有效。。。谢谢事实上,我甚至没有想过在删除之前将一侧设置为null。。。所以不管怎么说,我做错了。但是
    onDelete:SET NULL
    是关键。现在我明白了,这是有效的@尼克·朗很高兴我能帮上忙!