2014-04-29 55 views
4

我有一個處理所有數據庫操作的類。我已經讀過,最好將多個DataContext實例用於不同的讀/寫/更新/刪除操作,而不是一個長時間存在的DataContext實例。在每個函數中使用DataContext

這意味着每一個,它的讀/寫/更新功能/刪除數據庫需要做到這一點:

public int GetSomeID(string name) 
    { 
     using (XXDataContext context = new XXDataContext(connStr)) 
     { 
      ... 
     } 
    } 

    public int GetAnotherID(string name) 
    { 
     using (XXDataContext context = new XXDataContext(connStr)) 
     { 
      ... 
     } 
    } 

    public void WriteSomething(string text) 
    { 
     using (XXDataContext context = new XXDataContext(connStr)) 
     { 
      ... 
     } 
    } 

而不只是在構造函數中有這個使用()和具有上下文的私有成員變量可用於每個函數調用。

在每個函數調用中都保留創建一個新的DataContext的功能,是否可以在其他地方使用()來移動它,所以不是每個函數都必須包含該行?

+1

你可以在構造函數/析構函數中創建和清除,但這會使得清理工作進一步受到GC的支配。你可以重構這些方法來傳遞一個Func/Action到一個內部方法,該方法在內部使用和評估Func(但這是一個公平的少一點慣用法)。 – 48klocs

+0

如果這是一個Web應用程序,你可以隨時使用我的解決方案 - 每個請求一個數據庫上下文 - http://stackoverflow.com/a/10153406/1289283 – walther

+0

你可以看看使用一些AOP插件。例如:https://github.com/Fody/Usable – Veikedo

回答

5

可以使用的方法類似這樣以避免重新編寫代碼using

private static void WithContext(Action<XXDataContext> action) 
{ 
    using(XXDataContext context = new XXDataContext(connStr)) 
     action(context); 
}  
private static T WithContext<T>(Func<XXDataContext, T> function) 
{ 
    using(XXDataContext context = new XXDataContext(connStr)) 
     return function(context); 
} 

這允許你寫:

public int GetSomeID(string name) 
{ 
    WithContext(context => 
     { 
      //TODO use context 
     }); 
} 

如果這可以幫助你。

+0

我只是想看看帶有'Func'作爲參數的'WithContext' :)你已經完成了 – Veikedo

0

對不起,不直接回答你的問題:

您已經閱讀正確的事情。上下文實現Unit Of Work模式,並且應該像那樣使用。

但是可以有一個有效的情況下,當你需要在同一範圍內做一些操作,它會一直不錯正確的代碼那樣:

using(var dal = new MyDalUOW()) { 

    dal.Delete(s1); 
    dal.Update(s2); 
    dal.Get(s3); 

    dal.Commit() 
} 

爲了這個,你將創建您達爾類將實現IDisposable,將有方法Commit

public class BaseDal: IDisposable { 
    private MyDbContext _context; 

    public BaseDal() { _context = new MyDbContext; } 

    public void Commit() { _context.SaveChanges(); } 
} 

和所有的方法都使用_context進行操作。

所以你仍然會使用所有這些使用,但在代碼中使用你的DAL,而不是在DAL本身。

0

如果您在桌面/ windows應用程序中使用它,使用單個DataContext是沒有問題的,但是您必須明智地處理它(根據db技術,例如EF或linq2sql),以便將datacontext緩存數據與數據庫同步。還有一件事,你必須爲每個線程使用單獨的datacontext。

我在你的web應用程序(ASP NET),那麼建議使用它,這是很好的做法,創建每個請求在DataContext的一個新實例(和處置它完成請求)。

所以,這取決於您的解決方案。

0

好吧,考慮下面的代碼:

using (var fileStream = new FileStream(@"C:\temp\test.txt", FileMode.Open)) 
{ 
    var bytes = new byte[fileStream.Length]; 
    fileStream.Read(bytes, 0, (int)fileStream.Length); 

    var text = Encoding.Default.GetString(bytes); 

    Console.WriteLine(text); 
} 

它利用使用IDisposable類;就像DataContext一樣。現在,假設我們想擺脫那個using;我們可以這樣做:

Read(fileStream => 
{ 
    var bytes = new byte[fileStream.Length]; 
    fileStream.Read(bytes, 0, (int)fileStream.Length); 

    var text = Encoding.Default.GetString(bytes); 

    Console.WriteLine(text); 
}, @"C:\temp\test2.txt"); 

static void Read(Action<FileStream> action, string path) 
{ 
    using (var fileStream = new FileStream(path, FileMode.Open)) 
    { 
     action(fileStream); 
    } 
} 

給你注入你想同時確保using語句從方法去除,以執行代碼。此外,您可以保證將使用using聲明。這個程序的輸出如預期的那樣:

Hello, World! 
Hello, World; from an injected function! 
Press any key to continue . . .