【问题标题】:Entity Framework .Remove() vs. .DeleteObject()实体框架 .Remove() 与 .DeleteObject()
【发布时间】:2013-07-17 09:55:00
【问题描述】:

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

第一个在EntityCollection,第二个在ObjectContext

应该在什么时候使用它们?

一个比另一个更喜欢吗?

Remove() 返回 boolDeleteObject() 返回 void

【问题讨论】:

    标签: c# database entity-framework orm


    【解决方案1】:

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

    • ObjectContext.DeleteObject(entity) 在上下文中将实体标记为Deleted。 (之后是 EntityStateDeleted。)如果你之后调用 SaveChanges,EF 会向数据库发送一条 SQL DELETE 语句。如果没有违反数据库中的引用约束,实体将被删除,否则抛出异常。

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

        1234563调用SaveChanges 这个NULL 的值为childEntity 将被写入数据库(即删除两者之间的关系)。这发生在 SQL UPDATE 语句中。没有出现DELETE 语句。
    • 如果关系是必需(FK 不允许NULL 值)并且关系无法识别(这意味着外键不是孩子(复合)主键的一部分)您必须将孩子添加到另一个父母,或者您必须明确删除孩子(然后使用DeleteObject)。如果您不执行任何这些操作,则会违反引用约束,并且当您调用 SaveChanges 时,EF 将抛出异常 - 臭名昭著的 "The relationship could not be changed because one or more of the foreign-key properties is non-nullable" 异常或类似情况。

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

    我实际上对您链接的Remarks section on the MSDN page 有点困惑,因为它说:“如果关系具有引用完整性约束,则在依赖对象上调用 Remove 方法会标记关系和依赖对象删除。”。这对我来说似乎不精确甚至是错误的,因为上述所有三种情况都有“参照完整性约束”,但只有在最后一种情况下,实际上删除了孩子。 (除非他们的意思是“依赖对象”是一个参与识别关系的对象,但这将是一个不寻常的术语。)

    【讨论】:

    • 参考完整性维基百科:参考完整性是数据的一种属性,当它满足时,要求关系(表)的一个属性(列)的每个值作为另一个属性的值存在于不同的(或相同的)关系(表),所以当关系是可选的时,我们会破坏数据完整性规则
    • @Mohammadreza:如果您将NULL 解释为“不是一个值”(而不是我写的有时有点草率的“值NULL”),那么“可选关系”就不存在与参照完整性的定义相矛盾。
    • 那么ObjectContext.DeleteObject的EF Core版本是什么?
    【解决方案2】:

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

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

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

    值得注意的是设置.State = EntityState.Deleteddoes not trigger automatically detected change.(archive)

    【讨论】:

    • 好的,对于那些不赞成我的回答的人来说,这与 Slauma 无关 - 他们都指向相同的文档。我的解释了现实生活中的例子,而他的理论也是其中的一部分。
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 2010-10-30
    相关资源
    最近更新 更多