【问题标题】:attaching linq to sql datacontext to httpcontext in business layer将 linq 附加到 sql datacontext 到业务层中的 httpcontext
【发布时间】:2011-01-29 17:55:30
【问题描述】:

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

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;
        }
    }
}

【问题讨论】:

    标签: asp.net linq-to-sql datacontext


    【解决方案1】:

    您的想象是有道理的 - 使用 HTTP 请求上下文来存储内容 - 但是 不, 存储在当前 HttpContext 中的一次性对象不会在请求结束时自动被释放。不知何故,您将不得不自己处理。

    有一个“结束请求”事件,您可以轻松挂钩,例如使用放入 Global.asax.cs 的代码。在您的 Application_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 写了a relevant post on the topic a while ago,将您想要做的事情描述为一种模式,换句话说,就是一种应该重复的做事方式。他提供了一个类来帮助解决这个问题,延迟加载数据库上下文并将其放入当前上下文中。这种方法存在一些缺陷——您可以在该帖子的评论讨论中了解它们。 cmets中还引用了一堆相关文章。

    【讨论】:

      【解决方案2】:

      Cheeso 的代码将生成 InvalidOperationException "Collection was modified; enumeration operation may not execute",因为它正在尝试修改它正在迭代的 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;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-15
        • 1970-01-01
        相关资源
        最近更新 更多