我有两个实体,每个实体互相引用:Page
实体引用defaultUrl
和Url
实体引用page
。
这是周期性的,所以一旦我添加了一个页面和一个url相互引用的内容,我就无法删除它们。
我可以看到两种方法来解决它,但我不确定采用“学说”方式。
我无法弄清楚如何做这些......你知道吗?
谢谢!
答案 0 :(得分:2)
这是Doctrine设置它的方法。如前所述,您需要将至少一个外键设置为可为空。
还要考虑将onDelete级联设置为SET NULL。这将使删除过程更简单 - 在删除记录之前,您不必将密钥更新为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 }
答案 1 :(得分:1)
经验法则,在制作外键时,总是使一个可以为空或省略一个外键定义。
这允许循环中断。
最简单的情况(SQL语法,但是适用了sampe原则):
CREATE TABLE Employee (
EmployeeId INTEGER NOT NULL IDENTITY(1,1)
ManagerId INTEGER NOT 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)
)
我更喜欢在声明外键时始终跟踪图表并确保没有周期。在所有循环都被打破之前,我将省略最不危险的密钥。这样可以确保可以批量导出所有表,然后将批量导入到另一个数据库中。
编辑:我发现当你向书籍专家询问这个问题时,你会得到一个答案,例如在删除期间关闭外键。出于两个原因,这是错误的。首先,正常的事务操作不应该改变模式定义。其次,代码的其余部分需要外键,因此不会在应用程序代码中处理它;但是,模式修改有一个讨厌的习惯,即在事务中流血或锁定整个表。