本文介绍了将 linq 到 sql datacontext 附加到业务层中的 httpcontext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need my linq to sql datacontext to be available across my business/data layer for all my repository objects to access. However since this is a web app, I want to create and destroy it per request. I'm wondering if having a singleton class that can lazily create and attach the datacontext to current HttpContext would work. My question is: would the datacontext get disposed automatically when the request ends? Below is the code for what I'm thinking. Would this accomplish my purpose: have a thread-safe datacontext instance that is lazily available and is automatically disposed when the request ends?

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 中的一次性对象将请求结束时不会自动处理.不知何故,你将不得不自己处理它.

What you imagine makes sense - using the HTTP Request context to store stuff - but No, disposable objects stored in the current HttpContext will not auto-magically be disposed when the request ends. You will have to hande that yourself, somehow.

有一个结束请求"事件,您可以轻松挂钩,例如使用放入 Global.asax.cs 的代码.在 Application_EndRequest() 方法中,您可以对列表中需要它的每个对象手动调用 Dispose().

There is an "End Request" event that you can hook into easily, for example using code that you drop into Global.asax.cs. In your Application_EndRequest() method, you can call Dispose() manually on each object in the list that requires it.

一种方法是遍历上下文中的每个项目,测试 IDisposable,然后在适当时调用 Dispose.

One way to do it is to iterate through each item in the context, test for IDisposable, and then call Dispose if appropriate.

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 不会自动为您执行此操作.当然,在真正的应用程序中使用此代码之前,您需要防止异常等.

I think that oughtta do it. ASPNET doesn't do this for you automatically. Of course you need protection from exceptions and so on, before using this code in a real app.

Vertigo 的 Keith Craig 写道 前一段时间关于该主题的相关帖子,描述了您想要做什么作为一种模式,换句话说,一种做事的方式应该重复.他提供了一个类来帮助解决这个问题,延迟加载数据库上下文并将其放入当前上下文.这种方法存在一些缺陷 - 您可以在该帖子的评论讨论中阅读有关它们的信息.评论中还引用了一堆相关文章.

Keith Craig of Vertigo wrote a relevant post on the topic a while ago, describing what you want to do as a pattern, in other words a way of doing things that ought to be repeated. He provides a class to help out with that, to lazy load the DB context and drop it into the current context. There are some pitfalls with the approach - you can read about them in the comment discussion on that post. Also there are a bunch of related articles cited in the comments.

这篇关于将 linq 到 sql datacontext 附加到业务层中的 httpcontext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:45