我有一个返回SqlDataReader的方法(“GetDataReader”,让我们调用它)。它位于Singleton DataFactory类中,用于维护与数据库的持久连接。
这个问题是返回后,DataReader仍然“连接”到我的DataFactory中的Connection对象。所以,我必须确保调用GetDataReader的代码然后在返回的DataReader上调用Close(),否则,它会“锁定”Connection:
已经有一个与此命令关联的打开DataReader,必须先关闭它。
在从GetDataReader发回DataReader之前,如何“分离”DataReader?要么是,要么克隆它并发回克隆?我不想让调用代码总是明确地关闭它。
这里必须有一个最好的做法。
更新
感谢大家的意见。最重要的是,我需要失去使用DataReaders并切换到DataTables的习惯。它们更容易管理。
另外,感谢有关连接池的说明。我知道它,但只是没有把两个和两个放在一起,并意识到我正在重新发明轮子。
答案 0 :(得分:6)
DataReader必须保持与数据库的连接,直到您不再需要它们为止 - 这就是使用DataReader的本质,因此您无法“断开”它们。当您使用完数据阅读器后,您应该将其关闭(.Close()
),但之后就不能再使用了它。
从.NET 2.0开始,如果您使用的是SQL 2005或更高版本,则可以按照MARS的说明使用here(多个活动结果集)。这允许您为多个数据读取器使用单个连接,只需更改连接字符串即可。 但是,SqlDataReaders并不适合以您想要的方式传递代码。
或者(我认为您需要这样做),您可能希望使用DataSet / DataTables所在的断开连接的结果集。您使用SqlDataAdapter来填充DataSet / DataTable查询结果。然后,您可以将该连接用于任何其他目的,或关闭连接,它不会影响您的内存中结果集。您可以在代码周围传递结果集,而无需维护开放的数据库连接。
答案 1 :(得分:2)
不要坚持数据库连接。有一个称为“连接池”的功能。获得新的联系并不昂贵。
答案 2 :(得分:1)
通常,最佳做法是使用连接池而不是持久连接,以允许多个用户同时访问。我能想到做你想做的事的唯一方法是从阅读器加载一个DataSet并返回它。
答案 3 :(得分:0)
我认为您可能会将数据集(断开连接的嵌入数据)和数据集(无数据)混淆在一起。没有SqlCnnection的DataReader是......嗯......只是一个Reader,即没有数据; - )
我认为你的问题在于你的思路。我猜你是一个老学校的程序员,常常手工做。在dot net的“托管”世界中,很多东西都是为你管理的; ADO.NET已经有了一个有效的数据连接池系统,你不需要维护自己的池。
-Oisin
答案 4 :(得分: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();
}
}