問題描述
我需要我的 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的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!