Asp.net 将linq到sql datacontext连接到业务层中的httpcontext

Asp.net 将linq到sql datacontext连接到业务层中的httpcontext,asp.net,linq-to-sql,datacontext,Asp.net,Linq To Sql,Datacontext,我需要我的linq to sql datacontext在我的业务/数据层中可用,以便我的所有存储库对象都可以访问。但是,由于这是一个web应用程序,我想根据请求创建并销毁它。我想知道,如果有一个可以懒洋洋地创建datacontext并将其附加到当前HttpContext的singleton类,是否会起作用。我的问题是:当请求结束时,datacontext会自动被释放吗?下面是我所想的代码。这是否可以实现我的目的:拥有一个线程安全的datacontext实例,该实例是延迟可用的,并且在请求结束时

我需要我的linq to sql datacontext在我的业务/数据层中可用,以便我的所有存储库对象都可以访问。但是,由于这是一个web应用程序,我想根据请求创建并销毁它。我想知道,如果有一个可以懒洋洋地创建datacontext并将其附加到当前HttpContext的singleton类,是否会起作用。我的问题是:当请求结束时,datacontext会自动被释放吗?下面是我所想的代码。这是否可以实现我的目的:拥有一个线程安全的datacontext实例,该实例是延迟可用的,并且在请求结束时自动释放

public class SingletonDC
{
    public static NorthwindDataContext Default
    {
        get
        {
            NorthwindDataContext defaultInstance = (NorthwindDataContext)System.Web.HttpContext.Current.Items["datacontext"];
            if (defaultInstance == null)
            {
                defaultInstance = new NorthwindDataContext();
                System.Web.HttpContext.Current.Items.Add("datacontext", defaultInstance);
            }
            return defaultInstance;
        }
    }
}

您所想象的是有意义的——使用HTTP请求上下文来存储内容——但是,否,当前HttpContext中存储的一次性对象不会在请求结束时自动神奇地被处置。无论如何,你得自己处理

有一个“End Request”事件,您可以轻松地挂接到该事件中,例如使用放入Global.asax.cs的代码。在应用程序的EndRequest()方法中,可以对列表中需要它的每个对象手动调用
Dispose()

一种方法是迭代上下文中的每个项,测试IDisposable,然后在适当的情况下调用Dispose

protected void Application_EndRequest(Object sender, EventArgs e)
{
    foreach (var key in HttpContext.Current.Items.Keys) 
    {
        var disposable = HttpContext.Current.Items[key] as IDisposable;
        if (disposable != null)
        { 
           disposable.Dispose();
           HttpContext.Current.Items[key] = null; 
        } 
    }
}
我想应该这样做。ASPNET不会自动为您执行此操作。当然,在真正的应用程序中使用此代码之前,您需要防止出现异常等情况



Vertigo的基思·克雷格(Keith Craig)写道,将你想做的事情描述为一种模式,换句话说,是一种应该重复的做事方式。他提供了一个类来帮助实现这一点,即延迟加载DB上下文并将其放到当前上下文中。这种方法有一些缺陷——你可以在那篇文章的评论讨论中读到。评论中还引用了大量相关文章

Cheeso的代码将生成一个
InvalidOperationException
“集合已修改;枚举操作可能不会执行”
,因为它正试图修改它正在迭代的HttpContext项

您可以使用列表的副本来防止这种情况

protected void Application_EndRequest(Object sender, EventArgs e)
{
    var keys = new ArrayList(HttpContext.Current.Items.Keys);

    foreach (var key in keys)
    {
        var disposable = HttpContext.Current.Items[key] as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
            HttpContext.Current.Items[key] = null;
        }
    }
}