SqlCommand.ExecuteReader() 何时返回 null?

When would SqlCommand.ExecuteReader() return null?

提问人:Ray 提问时间:7/2/2009 更新时间:1/27/2021 访问量:11968

问:

使用调用该方法时,ReSharper告诉我,当我之后使用SqlDataReader对象时,我可能有一个NullReference异常。SqlCommand.ExecuteReader()

因此,使用以下代码:

using (SqlConnection connection = GetConnection())
{
    using (SqlCommand cmd = connection.CreateCommand())
    {
        cmd.CommandText = ; //snip

        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                //snip
            }
        }
    }
}

该行带有下划线。while (reader.Read())

我的问题是,读取器对象什么时候会为空?我从未遇到过它,文档也没有提到它可能。我应该检查它是否为 null 还是可以安全忽略?

为什么 ReSharper 会认为它可能是 null,例如,它允许我使用 SqlCommand 而不建议检查它是否为 null?我猜 ExecuteReader 方法上有一个属性。

.NET Resharper NullReferenceException SQL命令

评论


答:

2赞 John Saunders 7/2/2009 #1

我在其他几个领域也遇到了这个问题。他们似乎已经对 CLR 各个部分中的代码路径进行了分析。当他们发现返回 null 是可以想象的时,他们就会抱怨它。

在我抱怨的特定情况下,null 实际上不会发生。但是,他们将调用图跟踪到在某些情况下可以返回 null 的方法,并且 null 值可以传播到顶部。

因此,我称它为 ReSharper 错误(我以为我以前称它为 CLR 错误)。

12赞 Tatiana Racheva 7/2/2009 #2

这是一个误报。

反思 SqlDataReader.ExecuteReader,我可以看到读取器返回为 null 的唯一方式是,如果为 returnStream 传递了内部 RunExecuteReader 方法“false”,但事实并非如此。

在 SqlDataReader 的深处,读取器构造函数总是在某个时候被调用,所以我非常确定 ExecuteReader 在物理上不可能返回 null。

2赞 dmlinliverpool 1/18/2011 #3

我已经确定了 ExecuteReader() 可以返回 null 的一个原因。

在我得到 null 的情况下,我向客户端发送了一个脚本来更新存储过程。设置了客户端的 Sql Server (2000),以便数据库用户需要执行存储过程的权限。当他们更新 SP 时,权限被删除,而不是重新分配。在此实例中,SqlCommand.ExecuteReader() 返回 null。

重新分配权限解决了此问题。

4赞 G.Y 12/25/2013 #4

Resharper 是正确的,它可以返回 null 电位。

如果 的特定实现不允许冒泡 null 值,这并不重要 - 事实仍然是 IDataReader 是一个可以包含(或指向)null 的对象。ExecuteReader()

  • 如果将来您决定使用不同的实现怎么办?IDbCommand
  • 如果该 IDbCommnd 实现的下一次更新将在代码中包含不同的流,这将允许冒泡 null,该怎么办?

你不需要知道接口的实现内部发生了什么,就可以正确使用它 - 你只需要知道接口,现在接口允许 null 作为返回值。

0赞 David Klempfner 1/27/2021 #5

对我来说,它不是空的,但在 Powershell 中查看时不会输出任何内容。 当查询未返回任何行时,将发生这种情况。