[C#]DataAdapter的有趣現象

[C#]DataAdapter的有趣現象

今天在小舖的討論版上看到一個有趣的問題,看了一下版友lsk提到DataAdapter會自動Open/Close connection,這一點讓我有點驚訝,之前我們在寫資料庫連結時,應該是很乖的這樣寫:


using (SqlConnection tConnection = new SqlConnection(@"server=.;database=Northwind;uid=sa;pwd=sa"))
{
    SqlCommand tSqlCommand = tConnection.CreateCommand();
    tSqlCommand.CommandText = "Select * from Products";

    SqlDataAdapter tAdapter = new SqlDataAdapter();
    tAdapter.SelectCommand = tSqlCommand;

    DataSet tDataset = new DataSet();

    tConnection.Open();

    tAdapter.Fill(tDataset , "Products");

    tConnection.Close();
}

乖寶寶的寫法都在要執行SQL之前Open,並在執行完後Close,確保connection不會被長時間佔用。

結果今天發現,我這樣寫也可以,下面的程式我將Open/Close拿掉了:


using (SqlConnection tConnection = new SqlConnection(@"server=.;database=Northwind;uid=sa;pwd=sa"))
{
    SqlCommand tSqlCommand = tConnection.CreateCommand();
    tSqlCommand.CommandText = "Select * from Products";

    SqlDataAdapter tAdapter = new SqlDataAdapter();
    tAdapter.SelectCommand = tSqlCommand;

    DataSet tDataset = new DataSet();

    tAdapter.Fill(tDataset , "Products");
}

為了證明沒有唬爛,我們來偵錯看看吧,我把中斷點下在Fill的位置,這一行會執行資料讀取的動作,這時後發現Connection的State還是Closed:

image

 

Connection還沒Open,這時候執行SQL指令應該是必死的吧,但執行下去發現,真的有撈到資料,且執行完後Connection的State還是Closed:

image

看MSDN上的DataAdapter.Fill的說明:

Fill 方法使用相關的 SelectCommand 屬性所指定的 SELECT 陳述式,從資料來源擷取資料列。與 SELECT 陳述式關聯的連接物件必須是有效的,但不需要是開啟的。如果在呼叫 Fill 之前關閉連接,它會先開啟以擷取資料,然後再關閉。如果在呼叫 Fill 之前開啟連接,它會保持開啟。

原來DataAdapter會在需要時自動Open connection並在不需要時自動Close connection,挺聰明的,不過個人還是建議維持寫程式的好習慣,自己做Open/Close吧。

 

 

參考資料:

DataAdapter and Database Connections - Performance and Connection Pooling

DataAdapter and Database Connections and Connection Pooling - Part 2

DataAdapter.Fill 方法 (DataSet)

游舒帆 (gipi)

探索原力Co-founder,曾任TutorABC協理與鼎新電腦總監,並曾獲選兩屆微軟最有價值專家 ( MVP ),離開職場後創辦探索原力,致力於協助青少年培養面對未來的能力。認為教育與組織育才其實息息相關,都是在為未來儲備能量,2018年起成立為期一年的專題課程《職涯躍升的關鍵24堂課》,為培養台灣未來的領袖而努力。