【问题标题】:EF delete trying to update foreign keyEF删除尝试更新外键
【发布时间】:2013-12-17 13:48:47
【问题描述】:

假设我有这种情况:

Table Bar
Id int not null
Name string not null

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

当我尝试删除在 Foo 中有引用的 Bar 时,为什么 EF 尝试更新 Foo 将 BarId 设置为 NULL?

当有人尝试将 NULL 设置为 Bar 时,我对我的属性进行了验证,当 EF 尝试更新 Foo 时我收到此错误。

如果我尝试删除执行“从 foo 中删除 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);

【问题讨论】:

  • 由于约束,它尝试将 BarId 设置为 null。您没有级联删除,外键列需要一个值或空值。你能发布你的约束吗?
  • 但是我的专栏不接受 NULL。
  • 约束条件:ALTER TABLE [dbo].[Cargo] WITH CHECK ADD CONSTRAINT [CargoRaiz_Instituicao] FOREIGN KEY([Instituicao_Id]) REFERENCES [dbo].[Instituicao] ([Id])

标签: c# sql-server-2008 entity-framework entity-framework-4


【解决方案1】:

您可以使用这两种方法“从数据库中删除项目”通常是不正确的。准确来说是这样的:

ObjectContext.DeleteObject(entity) 在上下文中将实体标记为已删除。 (之后 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-20
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多