0

我有一個基於經典不同層次的n層應用程序:用戶界面,服務(WCF),業務邏輯和數據訪問。數據庫(Sql Server)顯然是通過實體框架被打破的,問題基本上是每個調用都從用戶界面開始並貫穿所有層,但這樣做需要每次爲每個操作創建一個新的ObjectContext,這使得性能非常糟糕,因爲每次我需要重新加載元數據並重新編譯查詢。實體框架和ObjectContext n層體系結構

最建議圖案這將是下面的一個,它是什麼,我實際上做:創造和傳遞新的上下文throught每個服務接收到呼叫

public BusinessObject GetQuery(){  
    using (MyObjectContext context = new MyObjectContext()){ 
     //..do something } } 

爲了便於實時業務層的方法查詢我沒有看到任何特定的dealy,它工作正常,但對於複雜和沉重的查詢,它使2秒鐘的查詢繼續每次調用15秒。

我可以設置ObjectContext靜態,它可以解決性能問題,但它似乎不被任何人建議,也因爲我不能同時從不同的線程和多個調用同時訪問上下文一個例外。我可以讓它成爲線程安全的,但長時間維持相同的ObjectContext會使它變得越來越大(並且越來越慢),因爲它導入的引用每個查詢都會執行查詢。

我擁有的體系結構我認爲這是最常見的,那麼實現和使用ObjectContext的最佳方法是什麼?

謝謝 馬爾科

回答

2

在Web方面,最好使用無狀態的方式,併爲每個請求創建一個ObjectContext

ObjectContext建設的成本是最小的。元數據從全局緩存中加載,因此只有第一次調用纔會加載它。

靜態絕對不是一個好主意。 ObjectContext不是線程保存,這將導致在多次調用WCF服務中使用它時出現問題。使線程保存會導致性能下降,並且在多個請求中重複使用時會導致細微的錯誤。

檢查此信息:How to decide on a lifetime for your ObjectContext

+0

是的,我已經讀了文章,這就是爲什麼我不使用Singleton模式,我不明白爲什麼當我每次創建一個新的objectcontext時,對於複雜查詢來說性能很糟糕 – MaRuf 2012-02-13 14:29:52

+0

'每次'都是什麼意思?那是在重新編譯你的代碼並啓動你的應用程序?還是多次執行一個函數? – 2012-02-13 14:33:22

+0

我的意思是每次用戶界面調用服務時,它會創建一個新的ObjectContext,執行一個查詢並返回一些結果,每次我執行此操作時它都很慢,如果我在同一個調用中執行此操作多次,第一次 – MaRuf 2012-02-13 14:36:43

0

你所展示的是使用情境的典型模式 - 按要求,類似於使用一個數據庫連接。

是什麼讓你覺得糟糕的表現與重新創建上下文有關?這很可能不是這種情況。你是如何衡量這種影響的?

如果你有這樣的性能關鍵代碼,這個開銷真的很重要,你不應該使用實體框架,因爲總會有一些開銷,即使在一般情況下開銷應該很小。我將開始專注於您的數據模型,以及底層的數據存儲,這將對您的查詢性能產生更大的影響。你有沒有優化你的查詢?你有沒有把索引放在你需要的地方?你能否取消規範化數據以刪除連接?

+0

我試圖在同一個電話多次執行相同的查詢,只有第一個需要很長時間,其他人幾乎需要花費相同的時間才能完成SQL Management Studio!和我使用單例模式並設置靜態ObjectContext時的行爲相同。所以我認爲這是當我聲明一個新的ObjectContext的問題,不是嗎? – MaRuf 2012-02-13 14:28:11

+0

您第一次初始化ObjectContext和MetaData。這就是爲什麼它第一次很慢。您的MetaData緩存每個AppDomain一次。 – 2012-02-13 14:32:34

+0

對不起,我不明白我在做什麼錯,每次我調用werbservice都會很慢,並且它會創建一個新的ObjectContext – MaRuf 2012-02-13 14:35:10

1

使用靜態對象上下文不是一個好主意。靜態上下文將由Web應用程序的所有用戶共享,這意味着當一個用戶對上下文進行修改(例如調用saveChanges)時,使用該上下文的所有其他用戶都將受到影響(假設他們已添加或更新,這會是一個問題數據到上下文但尚未調用保存更改)。處理對象上下文時的最佳做法是在請求期間保持活動狀態,並使用是否執行任何原子業務操作。您可能希望檢查出的UnitOfWork模式和存儲庫模式

uow

uow and repository in EF

如果你覺得你有與您的查詢的性能問題,還有就是你會重用你查詢的可能性,我會建議你使用預編譯的linq查詢。你可以看看下面的鏈接,瞭解更多信息

precompiled linq julie lermann

precompiled linq