2 回答
TA贡献1864条经验 获得超2个赞
使用这两种方法可以“ 从数据库中删除项目 ”通常不正确。确切地说,它是这样的:
ObjectContext.DeleteObject(entity)
在上下文中标记实体Deleted
。(它EntityState
是Deleted
后)。如果你打电话SaveChanges
后EF发送SQLDELETE
语句到数据库。如果违反了数据库中的引用约束,则将删除该实体,否则将引发异常。EntityCollection.Remove(childEntity)
标记父和childEntity
as 之间的关系Deleted
。如果childEntity
从数据库中删除了自身,并且在调用时确实发生了什么,SaveChanges
取决于两者之间的关系类型:如果关系是可选的,即从子级引用到数据库中的父级的外键允许
NULL
值,则此外部将被设置为null,如果调用SaveChanges
此NULL
值,则将该值childEntity
写入数据库(即两个被删除)。这发生在SQLUPDATE
语句中。没有DELETE
发表声明。如果需要关系(FK不允许
NULL
值)且关系未识别(这意味着外键不是子(复合)主键的一部分),则必须将子项添加到另一个父项或你必须明确删除孩子(DeleteObject
当时)。如果您不执行任何这些操作,则会违反参照约束,EF会在您调用时抛出异常SaveChanges
- 臭名昭着的“ 由于一个或多个外键属性不可为空而无法更改关系 ”异常或类似。如果关系正在识别(因为主键的任何部分都不可能是必需的
NULL
),EF也会标记childEntity
为Deleted
as。如果调用SaveChanges
SQLDELETE
语句将被发送到数据库。如果未违反数据库中的其他引用约束,则将删除该实体,否则将引发异常。
我实际上对您链接的MSDN页面上的 “ 备注”部分感到困惑,因为它说:“ 如果关系具有参照完整性约束,则在依赖对象上调用Remove方法会标记关系和依赖对象以进行删除。 ”。这对我来说似乎是不准确甚至是错误的,因为上面的所有三种情况都有“ 参照完整性约束 ”,但只有在最后一种情况下才会删除子。(除非它们与“ 依赖对象 ” 意味着一个参与识别关系的对象,但这可能是一个不寻常的术语。)
TA贡献1829条经验 获得超6个赞
如果你真的想使用Deleted,你必须使你的外键可以为空,但是你最终会得到孤立的记录(这是你不应该首先做的那个主要原因之一)。所以只需使用Remove()
ObjectContext.DeleteObject(entity)在上下文中将实体标记为已删除。(之后删除了EntityState。)如果之后调用SaveChanges,EF会向数据库发送SQL DELETE语句。如果违反了数据库中的引用约束,则将删除该实体,否则将引发异常。
EntityCollection.Remove(childEntity)将parent和childEntity之间的关系标记为已删除。如果从数据库中删除了childEntity本身,并且在调用SaveChanges时究竟发生了什么,取决于两者之间的关系类型:
值得注意的是,设置.State = EntityState.Deleted
不会触发自动检测到的更改。 (档案)
添加回答
举报