C# SQL连接限制和管理实体

C# SQL连接限制和管理实体,c#,asp.net,entity-framework,sql-server-2008-r2,garbage-collection,C#,Asp.net,Entity Framework,Sql Server 2008 R2,Garbage Collection,因此,我管理一个相当大的web应用程序,并设置了一种独特的方法来处理Entity Framework数据上下文,以帮助缓存页面上的不同事件。从我之前看到的情况来看,在实体框架中跨页面管理上下文基本上有两种方法: 创建为所有连接共享的静态上下文 将连接用作事件中的一次性连接 因为我们的数据变化太快,我不想使用静态上下文,所以我最初从每个事件中的一次性连接开始。这就成了问题,因为我们的页面相当健壮,并且由于不断打开和关闭上下文而导致大量开销。此外,这限制了我在页面中可以进行的缓存量,因为我必须为

因此,我管理一个相当大的web应用程序,并设置了一种独特的方法来处理Entity Framework数据上下文,以帮助缓存页面上的不同事件。从我之前看到的情况来看,在实体框架中跨页面管理上下文基本上有两种方法:

  • 创建为所有连接共享的静态上下文
  • 将连接用作事件中的一次性连接
因为我们的数据变化太快,我不想使用静态上下文,所以我最初从每个事件中的一次性连接开始。这就成了问题,因为我们的页面相当健壮,并且由于不断打开和关闭上下文而导致大量开销。此外,这限制了我在页面中可以进行的缓存量,因为我必须为每个事件提供新的数据。最后,我决定做一件我从未见过的新事情,那就是为每个请求打开一个上下文,并为整个请求保持它的打开状态。这使得两种方法和代码之间的灵活性最好,如下所示:

public class FrontEndPage : System.Web.UI.Page
{


    private PageContext _context;
    public Database.DatabaseEntities context
    {
        get 
        {
            if (_context == null)
                _context = new PageContext();
            return _context.Context;
        }
    }
}

public class PageContext
{

    public Database.DatabaseEntities Context;
    public PageContext()
    {
        Context = Database.DatabaseEntities();
    }
} 
这导致了一个新的有趣的问题。我开始在连接数据库时出现间歇性错误。一旦我刷新应用程序池,它就会消失。我能找到的唯一解释是,我处理db上下文的方法中的实体连接并不总是正确地处理,当垃圾收集无法清除连接时,它最终会留下打开的连接。大约一天后,它将使用Sql Server的连接限制,并导致以下错误

Named Pipes Provider, error: 40 - Could not open a connection to SQL Server
Server Error in '/' Application.
Access is denied
Description: An unhandled exception occurred during the execution of the current web equest. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ComponentModel.Win32Exception: Access is denied

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
从那时起,我已经将回收应用程序池的计划更新为4小时的增量,但这并不是一个永久的解决方案。由于我缓存的方式,我肯定想找到一种方法,使每个请求1个上下文的方法能够工作,因为它非常适合应用程序,但我需要一种方法来确保正确关闭任何打开的上下文

是否有更好的方法来处理此问题,或者有一种方法可以确保在请求完成后关闭此连接,以防止它挂起连接


或者错误可能是由其他原因引起的?

因此,我设法找到了解决此问题的最佳方法。我在自定义页面类中添加了一个页面卸载事件,用于检查是否存在打开的上下文并关闭连接。在这一点上,这是我发现的处理连接的最佳方法,因为它在保持缓存和确保对象始终是最新的方面提供了最大的平衡

protected void Page_Unload(Object sender, EventArgs e)
{
    if (_context != null)
    {
        if (_context.Context.Connection.State == ConnectionState.Open)
            _context.Context.Connection.Close();
        _context.Context.Dispose();
        _context.Context = null;
        _context = null;
    }
}