6

我有一个返回 SqlDataReader 的方法(“GetDataReader”,我们称之为)。它位于 Singleton DataFactory 类中,该类维护与数据库的持久连接。

这样做的问题是,在返回后,DataReader 仍然“连接”到我的 DataFactory 中的 Connection 对象。因此,我必须确保调用 GetDataReader 的代码然后在返回的 DataReader 上调用 Close(),否则,它会“锁定”连接:

已经有一个与此命令关联的打开的 DataReader,必须先关闭它。

在从 GetDataReader 发回 DataReader 之前,如何“分离”它?要么,或者克隆它并发送回克隆?我不想让调用代码总是显式地关闭它。

这里必须有一个最佳实践。

更新:

谢谢各位的意见。底线是我需要改掉使用 DataReaders 的习惯,改用 DataTables。它们更易于管理。

另外,感谢有关连接池的说明。我知道这一点,但只是没有把两个和两个放在一起并意识到我正在重新发明轮子。

4

5 回答 5

7

DataReader 必须保持与数据库的连接,直到您不再需要它们 - 这是使用 DataReader 的本质,因此您不能“断开”它们。当您使用完数据读取器后,您应该关闭它 ( .Close()),但之后您就不能再使用它了。

从 .NET 2.0 开始,如果您使用的是 SQL 2005 或更高版本,则可以使用MARS(多个活动结果集),如此所述。这允许您为多个数据读取器使用单个连接,并且只涉及对连接字符串的更改。但是,SqlDataReaders 并不适合以您想要的方式传递您的代码。

或者(我认为您需要这样做),您可能想要使用断开连接的结果集,这是 DataSet/DataTables 的来源。您使用SqlDataAdapter用查询的所有结果填充 DataSet/DataTable。然后,您可以将连接用于任何其他目的,或关闭连接,这不会影响您的内存结果集。您可以在代码周围传递结果集,而无需维护打开的数据库连接。

于 2010-01-18T15:31:25.303 回答
2

不要持久化你的数据库连接。有一个称为“连接池”的功能。获得新的连接并不昂贵。

于 2010-01-18T15:30:11.823 回答
1

通常,最佳实践是使用连接池而不是持久连接,以允许多个用户同时访问。我能想到的唯一方法是从阅读器加载一个 DataSet 并返回它。

于 2010-01-18T15:30:39.550 回答
1

我认为您可能将数据集(断开连接的嵌入式数据)和数据读取器(无数据)混淆了。没有 SqlCnnection 的 DataReader 是......嗯......只是一个阅读器,即没有数据 ;-)

我认为您的问题进一步超出了您的思路。我猜你是一个习惯于手工做所有事情的老派程序员。在点网的“托管”世界里,很多东西都为你托管;ADO.NET 已经有一个有效的数据连接池系统,您不需要维护自己的池。

-Oisin

于 2010-01-18T15:30:47.020 回答
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();
    }
}
于 2017-11-23T18:31:31.143 回答