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
是关键。现在我明白了,这是有效的@尼克·朗很高兴我能帮上忙!