gpt4 book ai didi

c# - EF delete 尝试更新外键

转载 作者:行者123 更新时间:2023-11-30 18:31:09 27 4
gpt4 key购买 nike

假设我有这个场景:

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 where 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。

这是我的 map :

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

最佳答案

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

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

EntityCollection.Remove(childEntity) 将父实体和子实体之间的关系标记为已删除。如果 childEntity 本身已从数据库中删除,那么当您调用 SaveChanges 时究竟发生了什么取决于两者之间的关系:

如果关系是可选的,即数据库中从子项到父项的外键允许 NULL 值,则此外键将设置为 null,如果您调用 SaveChanges,childEntity 的此 NULL 值将被写入数据库(即两者之间的关系被删除)。 SQL UPDATE 语句会发生这种情况。没有出现 DELETE 语句。

如果关系是必需的(FK 不允许 NULL 值)并且关系不是标识性的(这意味着外键不是 child 的(复合)主键的一部分),您必须添加 child 给另一个 parent ,或者您必须明确删除 child (然后使用 DeleteObject )。如果您不执行任何这些操作,则会违反引用约束,并且 EF 将在您调用 SaveChanges 时抛出异常 - 臭名昭着的“无法更改关系,因为一个或多个外键属性不可为空”异常或类似的。

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

我实际上对您链接的 MSDN 页面上的备注部分感到有点困惑,因为它说:“如果关系具有参照完整性约束,则在依赖对象上调用 Remove 方法会同时标记关系和依赖对象删除”。这对我来说似乎不精确甚至是错误的,因为上述所有三种情况都有“参照完整性约束”,但只有在最后一种情况下, child 实际上被删除了。 (除非他们用“依赖对象”表示参与识别关系的对象,尽管这将是一个不寻常的术语。)

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

关于c# - EF delete 尝试更新外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20635926/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com