2014-11-03 52 views
3

我寫了下面的代碼(修剪爲簡便起見):我什麼時候必須明確地打開一個SqlConnection?

using (SqlConnection cn = new SqlConnection("Server=test;Database=test;User=test;Password=test")) 
using (SqlDataAdapter da = new SqlDataAdapter()) 
using (DataSet ds = new DataSet()) 
{ 
    string groupsQuery = @"SELECT GroupName FROM tblGroups ORDER BY GroupName"; 

    da.SelectCommand = new SqlCommand(groupsQuery, cn); 
    da.Fill(ds); 

    foreach (System.Data.DataRow row in ds.Tables[0].Rows) 
    { 
     string group = row["GroupName"].ToString(); 
     this.GroupList.Add(group); 
    } 
} 

我忘了打電話給cn.Open(),但令我驚訝的是,代碼跑就好了。我懷疑SqlDataAdapter正在做一些魔術,於是我去找了the source

SqlDataAdapter從DbDataAdapter繼承Fill方法。

填充調用FillInternal,它封裝了邏輯塊,像這樣:

try { 
    QuietOpen(activeConnection, out originalState); 

    //... do the fill ... 
} 
finally { 
    QuietClose(activeConnection, originalState); 
} 

QuietOpenQuietClose非常簡單:

static private void QuietClose(IDbConnection connection, ConnectionState originalState) { 
    // close the connection if: 
    // * it was closed on first use and adapter has opened it, AND 
    // * provider's implementation did not ask to keep this connection open 
    if ((null != connection) && (ConnectionState.Closed == originalState)) { 
     // we don't have to check the current connection state because 
     // it is supposed to be safe to call Close multiple times 
     connection.Close(); 
    } 
} 

// QuietOpen needs to appear in the try {} finally { QuietClose } block 
// otherwise a possibility exists that an exception may be thrown, i.e. ThreadAbortException 
// where we would Open the connection and not close it 
static private void QuietOpen(IDbConnection connection, out ConnectionState originalState) { 
    Debug.Assert(null != connection, "QuietOpen: null connection"); 
    originalState = connection.State; 
    if (ConnectionState.Closed == originalState) { 
     connection.Open(); 
    } 
} 

我很好奇,當別人是我在SqlConnection上撥打Open我不需要需要?我應該總是明確地做,還是讓.NET「靜靜地」做它的事情?

此外,有關SqlDataAdapter爲什麼會這樣做的更多詳細信息的任何引用都會很好。

+1

雖然DataAdapter的工作方式如此,但DataReaders不會。 – LarsTech 2014-11-03 17:06:14

回答

2

this page on MSDN

Fill方法隱含打開連接DataAdapter的 使用如果發現連接尚未打開。如果填充 打開連接,它也關閉連接時,填充是 完成。

+0

但是如果你打開連接Fill不會關閉它?如果你打開它,你有責任關閉它? – 2014-11-03 17:15:34

+0

@PaulZahra這是正確的;如果你自己打開它,'Fill()'不會關閉它。 – 2014-11-03 20:00:57

相關問題