2010-02-28 86 views
3

我正在使用Linq to SQL,並在關於儘快關閉數據庫連接的博客文章中閱讀。作爲一個例子,他們展示了一個變量被轉換爲一個列表(使用.ToList()),而不是實際返回Linq查詢。我有以下代碼:我的數據庫連接是否關閉? (Linq to Sql)

public static bool HasPassword(string userId) 
{ 

    ProjDataContext db = new ProjDataContext(); 

    bool hasPassword = (from p in db.tblSpecUser 
            where p.UserID == userId 
            select p.HasPassword).FirstOrDefault(); 


    return hasPassword; 
} 

查詢是否正常?或者將數據庫連接保持打開的時間超過了必要的時間?

感謝您的任何意見

回答

5

連接將被自動管理。但是,(或者至少可以像評論所建議的那樣)與DataContext關聯的其他資源。直到DataContext被垃圾收集器銷燬後,這些資源纔會被釋放。因此,確保在不再需要DataContext時調用dispose通常會更好。

using (ProjDataContext db = new ProjDataContext()) { 
    bool hasPassword = (from p in db.tblSpecUser 
            where p.UserID == userId 
            select p.HasPassword).FirstOrDefault(); 


    return hasPassword; 
} 

這確保了db.Dispose()是當使用塊退出,從而關閉所述連接顯式調用。

編輯:繼我看着DataContext的討論出售自己(也使用反射),發現下面的代碼(FW 3.5),它會從DataContext.Dispose稱爲:

protected virtual void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     if (this.provider != null) 
     { 
      this.provider.Dispose(); 
      this.provider = null; 
     } 
     this.services = null; 
     this.tables = null; 
     this.loadOptions = null; 
    } 
} 

所以有這被釋放的資源:

  • 可以持有DbConnection的供應商,一個LO g(TextWriter)和DbTransaction
  • CommonDataServices
  • 表字典。
  • LoadOptions

供應商可能持有需要處理的資源(DbConnectionDbTransaction)。根據用戶已經分配給DataContext的記錄機制的例如TextWriter,日誌的TextWriter也可能必須被丟棄。一個FileWriter然後自動關閉。

就我所瞭解的其他屬性而言,沒有過多考慮細節,只有內存,但這也可用於通過dispose方法進行垃圾回收,但是,在內存實際上獲得釋放。

所以,最後我完全casparOne的說法:

一般來說,共享數據訪問的資源,如這是一個壞主意。

您應該創建資源來訪問數據庫,執行操作,然後在完成後處理它們。

+0

哇,感謝您的快速回復!我將替換所有我的projdatacontext代碼以使用'using'方法,而不是創建新實例並等待其調用的Dispose方法。再次感謝您的幫助。 – 2010-02-28 19:21:24

+1

值得注意的是,雖然IDisposable在Linq to SQL中實現,但Linq to SQL的設計者明確指出DataContext在大多數情況下不需要處理**。請參閱http://stackoverflow.com/questions/821574/c-linq-to-sql-should-datacontext-be-disposed-using-idisposable/821595 – 2010-02-28 19:32:36

+0

感謝您的信息。如果我理解正確,這是否意味着雖然'使用'適用於需要對GC時序進行更嚴格控制的情況,但是在使用DataContext時(大部分時間)並不需要這麼做嗎? – 2010-02-28 19:57:04

0

使用LINQ到SQL您一般不需要關心具體打開和關閉是上下文對象(在你的例子分貝)的一部分連接。關於你唯一需要特別這麼做的情況是,如果你通過上下文對象發送直接的SQL調用,而不是使用Linq。

對於L2S,通常需要創建上下文對象,完成工作單元,然後儘快處理對象。你的代碼示例對我來說看起來很好。

0

我認爲是使用using語句一個很好的做法。但我認爲你的查詢沒有什麼不好。

public static bool HasPassword(string userId) 
{ 

    using(var db = new ProjDataContext()) 
    { 

     bool hasPassword = (from p in db.tblSpecUser 
            where p.UserID == userId 
            select p.HasPassword).FirstOrDefault(); 


     return hasPassword; 
    } 
} 
0

數據庫連接將在您的數據庫對象不再存在(處置)或顯式關閉後立即關閉。 在您的示例中,它會收集(遲早)垃圾。

2

實現的角度來看,不,你沒有什麼可擔心的。但是,這不是由於查詢,而是由於管理DataContext本身。

DataContext類實現IDisposable接口,所以你應該調用Dispose DataContext的實現,只要你用它做。

現在,這是一個well known fact that calling Dispose on DataContext instances do nothing, and therefore are not technically required

不幸的是,這也是非常糟糕的做法。您應始終編碼合同,而不是實施。因爲DataContext的實現IDisposable,你應該關閉它,即使你知道它什麼都不做因爲這會絕對變化在未來實現。

另外,如果你切換到另一個LINQ提供程序,說LINQ到實體,那麼你必須調用Dispose,當你做了,因爲在ObjectContext實例數據庫連接的壽命(這也實現了IDisposable)是非常不同,並且對Dispose的調用會影響這些數據庫連接。

所有的說法,你有更大的關注。如果您共享一個DataContext,那麼您有可能跟蹤太多的對象。除非您已將ObjectTrackingEnabled property設置爲false,否則DataContext正在跟蹤通過它選擇的每個對象。如果您在應用程序的整個生命週期內沒有執行更新操作(或者甚至是您的更新操作),則專用於在共享DataContext上進行對象跟蹤的資源數量可能會相當可觀。

規則制定使用其他數據庫技術(例如在classes in the System.Data.SqlClient namespace)仍然適用。

一般來說,像這樣共享數據訪問資源是一個壞主意。

您應該創建資源來訪問數據庫,執行您的操作,然後在完成時予以處置。

+0

感謝您的帖子。我發佈的代碼非常多,我已經實現了我的DAL中的所有方法。如果我在代碼中爲每個方法創建一個新實例,我仍然共享DataContext的嗎? – 2010-02-28 20:00:21

+0

@ o-logn:不,如果你在需要的時候創建一個新的實例(比如說,在一個使用語句中,每個操作創建和處理它),那麼這就是上面提到的「對合同進行編碼」正確的方式來使用DataContext實例,IMO。 – casperOne 2010-02-28 23:51:44

+0

啊,這是一種解脫。以爲我是在一個巨大的重新編碼會議:)。謝謝! – 2010-03-01 01:34:45