entity framework.Remove()与.DeleteObject()

您可以使用以下两种方法使用EF从数据库中删除项目。

  • EntityCollection.Remove方法

  • ObjectContext.DeleteObject方法

第一个是EntityCollection ,第二个是ObjectContext

什么时候应该使用?

一个人比另一个人更喜欢吗?

Remove()返回一个boolDeleteObject()返回void

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

  • ObjectContext.DeleteObject(entity)在上下文中将实体标记Deleted 。 (之后它的EntityStateDeleted 。)如果您以后调用SaveChanges ,EF会向数据库发送一条SQL DELETE语句。 如果数据库中没有引用约束被侵犯,实体将被删除,否则引发exception。

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

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

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

    • 如果关系是确定的 (因为主键的任何部分都不能是NULL所以必须这样做),那么EF会将childEntity标记为Deleted 。 如果调用SaveChanges则会将SQL DELETE语句发送到数据库。 如果数据库中没有其他引用约束被违犯,则实体将被删除,否则抛出exception。

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

如果你真的想使用Deleted,你必须让你的外键可以为空,但是你最终会得到孤立的logging(这是你不应该这样做的主要原因之一)。 所以只需使用Remove()

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

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

值得注意的一点是,设置.State = EntityState.Deleted 不会触发自动检测到的更改。 ( 档案 )