为什么需要在UnitOfWork EF上实现Dispose模式?

tes*_*der 1 c# asp.net-mvc dispose entity-framework unit-of-work

微软教程http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp -net-mvc-application建议实现dispose模式,如下所示:

private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
Run Code Online (Sandbox Code Playgroud)

为什么我应该这样做,为什么我不能简单地处理上下文和足够的,如果我只使用会发生什么:

context.Dispose()
Run Code Online (Sandbox Code Playgroud)

实施微软部署模式的目标是什么?

Sla*_*uma 5

你可以用......

    public void Dispose() // IDisposable implementation
    {
        context.Dispose();
    }
Run Code Online (Sandbox Code Playgroud)

...没有虚拟Dispose过载而没有私有disposed标志,因为

  • 上下文本身检查是否Dispose已经被调用,以便在第二次调用时没有任何反应,并且不会抛出任何异常
  • 上下文类有自己的终结器,如果你没有Dispose显式调用,它将确保在垃圾收集时释放数据库连接

最后一点并不意味着你根本不需要调用context.Dispose(),因为垃圾收集器最终确定上下文的时间点是不确定的,它可能晚于你创建一个新的上下文实例时的点,使用它可能与相同的实体 - 这可能会导致一些麻烦.所以:始终明确地或通过using块来处理上下文.

我也怀疑GC.SuppressFinalize(this);这里有什么影响,因为你的类中没有终结器也没有基类,所以没有什么可以抑制的.

在我看来,您的示例中的模式是一个片段(错过了终结器/析构函数实现),如果您必须在类中处理自己的非托管资源,这可能很有用.但对于您的UnitOfWork类,您不必这样做.非托管资源(数据库连接)由上下文管理,您只需通过调用将工作委托给它context.Dispose().