2010-07-29 109 views
2

我剛開始使用EF4與存儲庫模式。我不得不在每次使用上下文之後調用dispose方法,或者在使用塊中將代碼包裝在周圍。我可以在不寫每一個方法的情況下使用ObjectContext,或者在存儲庫中處理這個問題有更好的方法。
另外我不想從UI中傳遞ObjectContext到存儲庫。實體框架4 ObjectContext生命週期

回答

2

使用對象上下文的一般模式是:

public BusinessObject GetSomething(){ 
    using (MyObjectContext context = new MyObjectContext()){ 
     //..do fun stuff 
    } 

} 

哪些希望是你正在使用的模式。只要使用「使用」語句,調用dispose似乎有點矯枉過正。

另一種選擇是如果您要在流中執行多個數據庫查詢。我已經看到了一種模式,可以在線程中重用相同的上下文。人們基本上實現了一個基於線程的單例模式並傳遞上下文。這樣做的好處是不需要重建上下文,以及一些內存緩存。缺點是你可能遇到併發問題。有人正在更新您在EF內部緩存的內容。

我猜測第二種情況並不適用,因爲它聽起來像是在寫一個小應用程序。 (該陳述是基於您關於從UI傳遞上下文的評論......這個陳述會嚇倒任何優秀的代碼架構師)。

如果您對基於線程的單例感興趣。首先了解Singleton模式,然後查看有關「DataContext」線程的blog。您將不得不將「DataContext」類型更改爲ObjectContext類,但它會起作用。

編輯

我會說我忽略了一個顯而易見的解決方案,這將是下文)。只需使用基於屬性的對象上下文並在使用語句中播放您的存儲庫即可。這將與上面的使用示例相同,但您會實現IDisoposable。

5

爲了儘可能有效地做到這一點,而無需依賴注入,我建議你爲對象上下文實現一個私有的延遲加載屬性。

private ObjectContext _context; 
private ObjectContext Context 
{ get 
    { 
     return _context ?? (_context = new ObjectContext()); 
    } 
} 

接下來,讓你的倉庫實施IDisposable和照顧對象範圍內的在您的Dispose方法:

public Repository : IDisposable 
{ 
    ... 
    public void Dispose() 
    { 
     _context.Dispose(); 
    } 
} 

然後你只需要使用所有的方法的財產,包裝的使用您的存儲庫在using聲明。

爲了減少到數據庫的流量,還可以將保存到存儲庫上的一個單獨方法中,該方法僅將該調用轉發給對象上下文。這樣你可以獲得更多的控制數據保存在UI層,即使你不控制如何。這意味着你可以做

using (var repo = new Repository()) 
{ 
    repo.AddSomeStuff("this", "is", true); 
    repo.ChangeSomethingElse("yes, please"); 
    repo.Save(); 
} 

並且只有一個從EF調用到數據庫。另一方面,如果你做

using (var repo = new Repository()) 
{ 
    repo.AddSomeStuff("this", "is", true); 
    repo.ChangeSomethingElse("yes, please"); 
} 

什麼也沒有發生,這可能會讓人困惑。