【问题标题】:How to maintain data after DbSet.Remove?DbSet.Remove 后如何维护数据?
【发布时间】:2014-11-27 23:22:18
【问题描述】:

我使用存储库模式并且为了使事情集中化,我创建了一个 IValidate 接口,我的每个存储库都可以实现该接口。在那我根据他们的状态进行实体验证。到目前为止一切顺利,直到我删除了一个实体。当我尝试从已删除的实体访问属性时,出现异常,该实体不再位于上下文中。

例如:

class A
{
   int MyClassBId
   B MyClassB
}

如果我添加或更新实体A,我可以轻松访问A.MyClassB。但是,如果我什至在调用 SaveChanges 之前删除(DbSet.Remove)(我的方法当然在保存之前调用此验证),则引用为空。因此,如果我再次尝试访问A.MyClassB,我会得到空引用,但存在“非延迟加载”对象。例如,A.MyClassBId 仍然有 B 的 FK。

我知道 DbSet.Remove 仅将实体标记为删除,没有别的。它是否也将其从上下文中删除?我该如何解决这个问题?调用 DbSet.Remove 并仍然维护对象中的引用,至少在调用 SaveChanges 之前?

谢谢。

【问题讨论】:

    标签: c# entity-framework entity-framework-6 repository-pattern


    【解决方案1】:

    您必须了解正在进行的两个过程:

    1. Entity Framework 跟踪在DbContext 中加载的实体,将它们的状态保持为AddedModifiedDeletedUnchanged。您可以通过MyDataContext.Entry(MyEntity).Statecall 进行检查。
    2. 从表面上看,POCO 类的行为就像您对与 ORM 没有任何连接的类所期望的一样。

    所以当您调用 DbSet.Remove 方法时会发生什么,实体将被标记为在幕后删除,并且从表面上看,它也会从它所属的 ICollection 中删除。

    如果您想跟踪应在 SaveChanges 调用中删除的实体,您必须在实体上定义 WillBeDeleted 属性,并且您的代码在计算活动实体时必须考虑此属性,验证等。实际的DbSet.Remove 调用应该在调用SaveChanges 之前进行。

    或者,您可以在初始化 DbContext 之前使用MyDataContext.Configuration.AutoDetectChangesEnabled=False。现在,受DbSet.Remove 方法约束的实体不会从 POCO 类中的ICollection 中删除,但是如果不再次在您的属性中跟踪它,您将无法知道该实体将被删除拥有。

    【讨论】:

    • 我想过在每个 POCO 类上添加一个属性的方法,但这似乎有点贵。我错了吗?关于第二个建议,如果我设置我还需要额外的属性,我不想阻止 EF 跟踪更改。等待你的回复。感谢您的回答。
    • 如果新的WillBeDeleted 属性进入数据库只会有点贵,这是不必要的。您可以通过将属性注释为<NotMapped> 来防止这种情况发生。在您对实体进行的每个枚举或计数中,都必须考虑到 WillBeDeleted 属性。至少我没有看到解决办法,因此不得不修复许多错误,但我们已经实现了它。
    • 关于阻止 EF 跟踪更改:这在许多情况下相当是个好主意,因为它可以提高性能,但我同意默认禁用它是不明智的。跨度>
    • 好的,Dabblernl,那我就这么做了...如果您能原谅我,我有一些不需要的更改要对我的代码执行:D 再次感谢。
    猜你喜欢
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多