2010-01-18 41 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(); 
    } 
}