2010-01-18 44 views
6

我有一個返回SqlDataReader的方法(「GetDataReader」,讓我們來調用它)。它位於一個Singleton DataFactory類中,該類維護與數據庫的持久連接。如何從SqlConnection對象中「分離」SqlDataReader?

問題是,返回後,DataReader仍然「連接」到我的DataFactory中的Connection對象。所以,我必須確保調用GetDataReader然後調用Close()上回來DataReader的代碼,否則,「鎖定」的銜接這樣的:

已經有與此相關聯的打開的DataReader必須先關閉的命令。

如何在將數據讀取器從GetDataReader發回之前「分離」DataReader?要麼,要麼克隆它併發回克隆?我不想讓調用代碼總是明確地關閉它。

這裏必須有一個最佳實踐。

更新:

謝謝大家對您的輸入。底線是我需要失去使用DataReader並切換到DataTable的習慣。他們更易於管理。

此外,感謝關​​於連接池的說明。我知道這件事,但只是沒有把兩個和兩個放在一起,並意識到我正在重新發明輪子。

+0

我已經得到了* *停止使用的DataReader ... – Deane 2010-01-18 16:01:56

回答

6

的DataReader的,必須保持連接到數據庫,直到你不再需要它們 - 這是使用DataReader所以你不能「斷開」他們這樣的性質。當您完成數據讀取器時,應關閉它(.Close()),但不能再使用它了。

從.NET 2.0開始,如果您使用的是SQL 2005或更高版本,則可以使用MARS(多活動結果集),如here所述。這使您可以爲多個數據讀取器使用單個連接,只需更改連接字符串即可。 但是,SqlDataReaders並不適合以您想要的方式傳遞代碼。或者(我認爲你需要這樣做),你可能想要使用一個未連接的結果集,它是DataSet/DataTables的來源。你使用SqlDataAdapter來填充一個DataSet/DataTable,其中包含了所有的結果查詢。然後,您可以將連接用於任何其他目的,或者關閉連接,並且不會影響您的內存結果集。你可以在你的代碼中傳遞你的結果集,而不需要維護一個開放的數據庫連接。

+0

是,數據表是一個更好的方法在這裏。我需要停止使用DataReader。我之前遇到過這個問題 - 希望這次我會吸取教訓。謝謝。 – Deane 2010-01-18 16:13:02

2

不要堅持你的數據庫連接。有一個稱爲「連接池」的功能。獲得新的連接並不昂貴。

1

通常,最佳做法是使用連接池而不是持久連接,以允許多個用戶同時訪問。我能想到的唯一方法就是從讀取器加載一個DataSet並返回它。

0

我想你可能會讓你的數據集(斷開連接的嵌入式數據)和datareaders(沒有數據)混合起來。沒有SqlCnnection的DataReader是... ummm ...只是一個Reader,即沒有數據;-)

我認爲你的問題是進一步思考的問題。我猜你是一位老派程序員,曾經手工做過所有事情。在網絡的「管理」世界中,許多事情都是爲你管理的; ADO.NET已經有了一個有效的數據連接池系統,你不需要維護你自己的池。

-Oisin

0

這裏有一個方便的輔助方法來執行一些SQL對的連接,並將它與服務器斷開連接:

public static DbDataReader ExecuteReaderClient(DbConnection connection, DbTransaction transaction, String commandText) 
{ 
    DbCommand command = connection.CreateCommand(); 
    command.CommandText = commandText; 
    if (transaction != null) 
     command.Transaction = transaction; 

    DbDataAdapter adapter = DbProviderFactories.GetFactory(connection).CreateDataAdapter(); 

    adapter.SelectCommand = command; 
    DataSet dataset = new DataSet(); 

    try 
    { 
     adapter.Fill(dataset); 
    } 
    catch (Exception e) 
    { 
     throw new Exception(
        e.Message + "\r\n" + 
        "Command Text" + "\r\n" + 
        commandText, e); 
    } 

    try 
    { 
     return dataset.CreateDataReader(); 
    } 
    finally 
    { 
     dataset.Dispose(); 
    } 
}