2009-06-02 109 views
8

在我已經運行跨Web應用程序LinqToSql靜態DataContext的,我發現下面的代碼來處理的DataContext與LinqToSQL打交道時在Web應用程序

public partial class DbDataContext 
    { 
    public static DbDataContext DB 
    { 
     get 
     { 
     if (HttpContext.Current.Items["DB"] == null) 
      HttpContext.Current.Items["DB"] = new DbDataContext(); 
     return (DbDataContext)HttpContext.Current.Items["DB"]; 
     } 
    } 
    } 

然後引用它以後這樣做:

DbDataContext.DB.Accounts.Single(a => a.accountId == accountId).guid = newGuid; 
DbDataContext.DB.SubmitChanges(); 

我一直在研究處理LinqToSQL的最佳實踐。

我不確定這種方法在處理DataContext時不是ThreadSafe並保留它的靜態副本。

這是一個很好的方法來接受一個Web應用程序?

@ Longhorn213 - 基於你所說的和我已經閱讀到HttpContext的更多,因此,我認爲你是對的。但是在我繼承的應用程序中,這是令人困惑的,因爲在每個方法開始時,它們都會重新查詢db以獲取信息,然後修改datacontext的實例並在其上提交更改。

由此,我認爲這種方法應該是不鼓勵的,因爲它給人的錯誤印象是datacontext是靜態的並且在請求之間持續存在。如果未來的開發人員認爲在方法開始時重新查詢數據是因爲他們認爲數據已經存在,他們可能會遇到問題並且不明白爲什麼。

所以我想我的問題是,如果這種方法在未來的發展中不鼓勵?

+0

這裏有一個很好的帖子,詳細介紹:http://blog.stevensanderson.com/2007/11/29/linq-to-sql-the-multi-tier-story/ – 2010-02-03 00:28:49

+0

我們只是推出了這個概念的一個變種今晚出門。 – 2010-02-12 10:01:32

回答

6

這不是一個靜態副本。請注意,該屬性從Context.Items中檢索它,這是每個請求。這是DataContext的每個請求副本,通過靜態屬性訪問。

另一方面,此屬性假設每個請求只有一個線程,這可能永遠不是真的。

0

A DataContext製造起來很便宜,你不會通過這種方式緩存。

0

我已經做了很多Linq到Sql的網絡應用程序,我不確定你有沒有工作。

datacontext應該跟蹤您對對象所做的更改,並且在此實例中不會這樣做。

所以當你碰到提交改變時,它不會知道你的任何對象在哪裏更新,因此不會更新數據庫。

您必須在斷開連接的環境(如Web應用程序)中對datacontext執行一些額外的工作。更新是最難的,但並不是那麼糟糕。我不會緩存並重新創建它。

+2

爲什麼不知道請求期間所做的更改? – 2009-06-02 17:49:42

0

此外,上下文本身並不是事務性的,所以理論上可能會發生另一個請求上的更新,並且更新可能會失敗。

0

我更喜歡創建一個頁面基類(從System.Web.UI.Page繼承),並公開一個DataContext屬性。它確保每頁請求都有一個DataContext實例。

這對我來說很好,它是一個很好的平衡恕我直言。你可以調用DataContext。在頁面末尾提交SubmitChanges(),並確保一切都被更新。您還要確保所有更改都是針對一個用戶。

通過靜態做這件事會導致痛苦 - 我擔心DataContext將失去跟蹤更改,因爲它試圖同時跟蹤許多用戶的更改。我不認爲它是爲此而設計的。