将 linq to sql datacontext 附加到业务层中的 httpcontext
我需要我的 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;
}
}
}
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;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的想象是有道理的 - 使用 HTTP 请求上下文来存储内容 - 但是不,存储在当前 HttpContext 中的一次性对象在请求结束时不会自动神奇地被处置。你必须以某种方式亲自处理它。
您可以轻松挂钩“结束请求”事件,例如使用放入 Global.asax.cs 中的代码。在 Application_EndRequest() 方法中,您可以对列表中需要它的每个对象手动调用
Dispose()
。一种方法是迭代上下文中的每个项目,测试 IDisposable,然后在适当的情况下调用 Dispose。
我认为应该这样做。 ASPNET 不会自动为您执行此操作。当然,在真正的应用程序中使用此代码之前,您需要防止异常等情况。
Vertigo 的 Keith Craig 写道 不久前关于该主题的相关帖子,描述了您想要作为一种模式做什么,换句话说,一种做应该做的事情的方式重复。他提供了一个类来帮助解决这个问题,延迟加载数据库上下文并将其放入当前上下文中。这种方法存在一些陷阱 - 您可以在该帖子的评论讨论中阅读它们。评论中还引用了一堆相关文章。
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.
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.One way to do it is to iterate through each item in the context, test for IDisposable, and then call Dispose if appropriate.
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.
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.
Cheeso 的代码将生成
InvalidOperationException
“集合已修改;枚举操作可能无法执行”
,因为它正在尝试修改正在迭代的 HttpContext 项。您可以使用列表的副本来防止这种情况。
Cheeso's code will generate an
InvalidOperationException
"Collection was modified; enumeration operation may not execute"
because it is trying to modify the HttpContext items that it's iterating over.You can use a copy of the list to prevent this.