在删除具有外键关系的记录时,我似乎偶然发现了一个EF6错误。我有一个包含3个一对多表的父表,以及2个一对一表。为了删除父记录,首先删除所有子记录,生成的SQL会跳过一对一表。这是一个示例和生成的SQL:
/* select the parent records we want to remove */
var parentTable = Database.EampleTable.Where(x => x.Id == header.Id).ToList();
/* select the data records we are going to remove */
var oneToMany1 = parentTable.SelectMany(x => x.OneToMany1);
var oneToMany2 = parentTable.SelectMany(x => x.OneToMany2);
var oneToMany3 = parentTable.SelectMany(x => x.OneToMany3);
var oneToOne1 = parentTable.Select(x => x.OneToOne1).First();
var oneToOne2 = parentTable.Select(x => x.OneToOne2).First();
/* Remove the one-to-many related records */
Database.OneToMany1.RemoveRange(oneToMany1);
Database.OneToMany2.RemoveRange(oneToMany2);
Database.OneToMany3.RemoveRange(oneToMany3);
/* Remove the one-to-one related records */
Database.OneToOne1.Remove(oneToOne1);
Database.OneToOne2.Remove(oneToOne2);
Database.ExampleTable.RemoveRange(table);
await Database.SaveChangesAsync(); /* exception: foreign key constraint violation */
生成的SQL:
-- Generated SQL by Entity Framework, upon delete
exec sp_executesql N'DELETE [dbo].[OneToMany1]
WHERE (([Id] = @0) AND ([OneToMany1Id] = @1))',N'@0 int,@1 int',@0=1,@1=1
go
exec sp_executesql N'DELETE [dbo].[OneToMany2]
WHERE (([Id] = @0) AND ([OneToMany2Id] = @1))',N'@0 int,@1 int',@0=1,@1=3
go
exec sp_executesql N'DELETE [dbo].[OneToMany3]
WHERE (([Id] = @0) AND ([OneToMany3Id] = @1))',N'@0 int,@1 int',@0=1,@1=11
go
exec sp_executesql N'DELETE [dbo].[ExampleTable]
WHERE ([Id] = @0)',N'@0 int',@0=1
go
如您所见,两个OneToOne表记录未被删除,因此删除父表的尝试会引发异常。作为有趣的旁注,如果我在代码中注释掉父表的delete语句,生成的SQL仍然是相同的,并且它正在尝试删除父表!
我倾注了模型文件和上下文寻找错误(以及其他人),并且根本就没有。现在我唯一的解决方案是手动编写所有查询,但我很想知道是否有其他人遇到过EF6这个问题。