如何判断SqlConnection是否附加了SqlDataReader?

Ear*_*rlz 12 .net c# sql ado.net

现在这更像是一种好奇而不是实际目的.如果你SqlConnection打开并附加一个SqlDataReader,然后尝试使用相同的运行另一个查询,SqlConnection那么它将抛出一个错误.我的问题是如何SqlConnection知道读者是否依附于它.没有公共财产或任何东西HasDataReader,所以SqlConnection班级怎么知道?


原始问题:(不再相关)

嗨,我正在为连接池和我们发生的更常见的错误设置一个小东西(它总是一个简单的修复,但我们只是记不起来reader.Close()!)它是我们有一个使用的连接通过许多类/方法和一种方法打开数据读取器并忘记关闭它.这并不是很糟糕,因为很多时候你需要做的就是进入调试器并升级到一个级别并在它之前看到它并检查它是否有一个未闭合的数据读取器.

现在,这是一个更大的问题.在这个连接池中,如果一个datareader是打开的,那么直到一个线程获得连接并尝试使用它并且最初打开数据读取器的东西可能不再存在时,它就不可知.

非常简单,如何检测数据读取器是否在连接上打开,是否有办法在不关闭连接的情况下关闭阅读器?

Joe*_*orn 13

确保关闭数据站(和数据库连接)的方法是始终在using块中打开它们,如下所示:

using (SqlDataReader rdr = MySqlCommandObject.ExecuteReader())
{
    while (rdr.Read())
    {
        //...
    }
} // The SqlDataReader is guaranteed to be closed here, even if an exception was thrown.
Run Code Online (Sandbox Code Playgroud)

  • 这一切都很好,但没有回答我的问题.我们已经开始使用`using`块,但我们仍然有旧的代码,但没有.在维护该代码时,可能会发生某些事情,以便读者不会被关闭.我们如何检测并抛出错误? (3认同)
  • 所以你不想改变你的旧版本以使其正确,而是添加一堆新代码来检测错误?那有点落后了. (2认同)

Yel*_*fog 13

SqlConnection如何知道读者是否附加到它上面

据我所知,SQLConnection知道它附有一个阅读器,因为它在内部维护了对它的引用.

明智地使用Reflector显示SQLConnection对象具有DBConnectionInternal类型的私有字段,该字段由此抽象类的许多具体实现之一填充.当您尝试向连接添加第二个实时读取器时,在内部连接上调用方法"ValidateConnectionForExecute",并且这将追溯到内部"ReferenceCollection"的检查.当这显示现有的实时阅读器时,会抛出异常.

我想,如果你想,你可以在运行时通过反射来挖掘所有这些.


小智 5

没有人真正回答厄尔兹的问题。(“为什么要这样做?”不是一个答案。)我认为答案是,仅通过查看连接本身无法判断连接是否具有与其关联的开放数据读取器。连接不会公开任何可以告诉您这一点的属性。打开连接将其 State 属性设置为 ConnectionState.Open。打开其上的数据读取器不会更改连接状态。仅当正在进行 SqlDataReader.Read() 等数据操作时才使用 ConnectionState.Fetching 等状态值。当连接位于读取之间时,连接状态只是打开。因此,要确定打开的读取器何时使用该连接,您必须检查可能正在使用该连接的读取器的状态。

  • 虽然乔尔没有“回答”这个问题,但他给出了正确的做事方法。特别是考虑到以错误的方式解决问题与正确的解决方案的复杂性相比,我非常不赞成(在文件中阅读、书面警告)任何尝试这种黑客解决方案而不是仅仅使用 USING 块的员工。 (2认同)
  • 我有同样的问题,这就是我正在寻找的确切答案。我有一个可重用的通用 DAL,其中外部实例化的连接对象作为参数传入,我需要确定它是否可重用。 (2认同)
  • 此外,有时我们无法自由地以正确的方式做事。有时我们会陷入错误的方式(由于封闭的依赖关系等),我们必须用我们拥有的东西来凑合。Stack Overflow 的答案至少应该先尝试回答问题,然后再描述世界应该如何运作。 (2认同)