2013-12-17 50 views
3

假设我有这样的场景:EF删除试图更新外键

Table Bar 
Id int not null 
Name string not null 

Table Foo 
Id int not nul 
BarId int foreign key (Bar) references Id 

当我尝试删除具有Foo中,参考为什么EF试图更新吧Foo将BarId设置为NULL?

我有一个验证我的财产,当有人试图设置为NULL条,并收到此错误时,EF试图更新富。

如果我尝试删除执行类似的查询“从富删除其中id = 1”我得到:

The DELETE statement conflicted with the REFERENCE constraint "FooFK". 
The conflict occurred in database "teste", table "dbo.Bar", column 'BarId'. 

我想,当我使用EF得到这个错误。有没有办法做到这一点? 我使用EF 4.3。

这是我的地图:

modelBuilder.Entity<Bar>().HasRequired(x => x.Foo).WithMany().Map(x => x.MapKey("FooId")).WillCascadeOnDelete(false); 
+0

它试图BarId设置为空由于该约束。您没有级联删除,并且外键列需要值或null。你能发布你的约束吗? – scheien

+0

但我的列不接受NULL。 –

+0

约束: ALTER TABLE [dbo]。[Cargo] WITH CHECK ADD CONSTRAINT [CargoRaiz_Instituicao] FOREIGN KEY([Instituicao_Id]) REFERENCES [dbo]。[Instituicao]([Id]) –

回答

0

它不是通常是正确的,你可以用两种方法“从数据库中删除项目”。确切地说,它是这样的:

ObjectContext.DeleteObject(entity)在上下文中将实体标记为Deleted。 (之后它的EntityState被删除。)如果您之后调用SaveChanges,则EF将SQL DELETE语句发送到数据库。如果数据库中没有引用约束被违犯,则实体将被删除,否则引发异常。

EntityCollection.Remove(childEntity)将parent和childEntity之间的关系标记为Deleted。如果从数据库中删除了childEntity本身,并且在调用SaveChanges时发生了什么取决于两者之间的关系类型:

如果关系是可选的,即从子项引用父项的外键数据库允许NULL值,这个外部将被设置为null,如果你调用SaveChanges,这个childEntity的NULL值将被写入数据库(即两者之间的关系被删除)。这发生在SQL UPDATE语句中。没有DELETE语句发生。

如果需要关系(FK不允许NULL值)并且关系不能识别(这意味着外键不是孩子的(复合)主键的一部分),您必须添加孩子到另一个家长,或者你必须显式删除孩子(然后使用DeleteObject)。如果您没有执行任何这些操作,则会违反引用约束,并且在您调用SaveChanges时EF会引发异常 - 臭名昭着的“由于一个或多个外键属性是不可空的,因此无法更改关系”异常或类似的。

如果关系正在识别(它必然需要,那么因为主键的任何部分都不能为空),EF会将childEntity标记为已删除。如果调用SaveChanges,则会将SQL DELETE语句发送到数据库。如果数据库中没有其他引用约束被违犯,则实体将被删除,否则引发异常。

我实际上对你关联的MSDN页面上的备注部分有点困惑,因为它说:“如果关系有一个参照完整性约束,调用依赖对象的Remove方法标记关系和依赖关系删除对象“。这对我来说似乎是不准确的,甚至是错误的,因为上述三种情况都有“参照完整性约束”,但只有在最后一种情况下才会删除孩子。 (除非他们的意思与“依赖对象”,在一个确定的关系这将是一个不寻常的术语虽然参与的对象。)

来源:http://bit.ly/1bNMyF5