如何将SqlDataReader与其SqlConnection对象“分离”?

7
我有一个方法(称之为“GetDataReader”),它返回一个SqlDataReader。它在一个单例DataFactory类中,该类维护与数据库的持久连接。
问题是,返回后,DataReader仍然与我的DataFactory中的Connection对象“连接”。所以,在调用GetDataReader的代码之后,我必须确保调用Close()来关闭返回的DataReader,否则会出现以下情况:“锁定”了Connection:
已经有一个与此命令关联的打开的DataReader,必须先关闭它。
如何在从GetDataReader发送回数据之前“分离”DataReader?要么这样,要么克隆它并发送克隆版?我不想让调用代码总是显式地将其关闭。
这里必须有最佳实践。
更新:
感谢大家的意见。底线是我需要摒弃使用DataReader的习惯,转而使用DataTables。它们更易于管理。
另外,感谢关于连接池的说明。我知道它,但只是没有将两个部分放在一起,意识到我正在重新发明轮子。

我必须停止使用DataReaders... - Deane
5个回答

7

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

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

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


是的,DataTables在这里是更好的方法。我需要停止使用DataReaders。我以前遇到过这个问题 - 希望这次我能吸取教训。谢谢。 - Deane

2

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


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

1

我认为你可能混淆了数据集(离线嵌入式数据)和数据读取器(无数据)。没有 SqlCnnection 的 DataReader 只是一个 Reader,也就是没有数据;-)

我认为你的问题在你的思路中更高层次。我猜你是一个老派程序员,习惯手动完成所有事情。在 dot net 的“托管”世界中,许多事情都是由系统管理的;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();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接