【问题标题】:What if I call DbContext.Dispose without calling DbContext.SaveChanges?如果我调用 DbContext.Dispose 而不调用 DbContext.SaveChanges 会怎样?
【发布时间】:2017-09-17 05:01:01
【问题描述】:

我正在寻找一种回滚实体更改的方法。我遇到了this answer,它显示了如何设置实体状态,但我想知道如果我只是处置我的dbContext 实例而不调用dbContext.SaveChanges() 或操作实体状态会发生什么。

我为此编写的代码确实有效,但我是否会因为以这种方式拒绝更改而使任何东西处于不稳定状态?

【问题讨论】:

    标签: .net entity-framework entity-framework-6 dbcontext rollback


    【解决方案1】:

    调用实现IDisposable 的类的Dispose() 方法意味着您正在告诉库“我已完成此对象。我将不再使用它。您可以根据需要进行清理。”这并不特定于实体框架。

    对于大多数类,在调用 Dispose() 后尝试继续使用该对象将会失败,有时会出现显式异常提醒您问题,有时是由损坏的对象状态引起的内部异常。你不应该假设 Entity Framework 是一个例外:在调用 dbContext.Dispose() 之后,你不应该再使用 dbContext 引用的上下文。

    但是,没有什么能阻止您在之后立即创建 新的 上下文:

    dbContext.Dispose();
    dbContext = new DbContext();
    

    这个新上下文绝对不会记得您在旧上下文中所做的任何未保存的更改。有很多好的案例表明这种方法是最实用的。

    【讨论】:

      【解决方案2】:

      没有东西会处于不稳定状态,所以不用担心。如果您在处置后尝试调用上下文,您将得到ObjectDisposedException,否则如果您不再需要它,处置它是合法的。

      【讨论】:

        【解决方案3】:

        如果我简单地处置我的 dbContext 实例而不调用 dbContext.SaveChanges() 或操作实体状态会发生什么

        什么都没有。以前附加到现在已处理的DbContext 实例的实例继续存在,因为任何普通实例都会假设在某处某处对这些实例有句柄。如果没有,内存将被释放并最终被垃圾收集,就像没有句柄的情况下任何其他正常实例一样。内存中实体的状态保持原样,内存中的任何内容都不会自动恢复。数据库存储也保持“原样”,这意味着没有从 DbContext 调用数据存储。

        我是不是通过以这种方式拒绝更改而使任何东西处于不稳定状态

        不,至少不在数据存储中。在内存中很难说,这取决于代码停止的位置以及直到那时为止修改的依赖关系。让我们假设它是一个无状态的 asp.net 应用程序,也许请求只是结束了,在这种情况下,以下任何请求都不会发生任何不稳定的情况,因为它们应该从数据存储中检索所需的任何内容。

        如果它的寿命更长,例如 Windows 应用程序,那么您可能必须手动确保任何指向之前被跟踪的实例的指针/句柄要么使用现在恢复的内存状态进行更新,要么释放这些指针。

        就任何新的 DbContext 实例而言,它们都彼此独立运行,因此它们之间没有延续。新的 DbContext 不知道正在跟踪的状态或任何其他 DbContext 实例已跟踪的状态。

        【讨论】:

        • 这是唯一真正解决我问题的答案。它没有解释处置的工作原理,而是关注 DbContext 本身内的实体。总之,你说的有道理。只要没有对它们的引用,上下文中的实体就会像任何其他要被 GC 的对象一样存在。如果我不调用.SaveChanges(),更改将不会推送到数据库。我很可能很快就会将此标记为答案
        猜你喜欢
        • 1970-01-01
        • 2011-01-15
        • 2021-05-10
        • 1970-01-01
        • 2020-04-16
        • 2010-11-18
        • 1970-01-01
        • 2021-06-06
        相关资源
        最近更新 更多