12

使用调用该SqlCommand.ExecuteReader()方法时,ReSharper 告诉我在之后使用 SqlDataReader 对象时可能会出现 NullReference 异常。

因此,使用以下代码:

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

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

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

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

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

4

5 回答 5

12

这是一个误报。

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

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

于 2009-07-02T03:03:59.353 回答
4

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

一个特定的实现是否ExecuteReader()不允许冒泡一个空值并不重要——事实上,IDataReader 是一个可以包含(或指向)空值的对象。

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

为了正确使用接口,您不需要知道接口实现内部发生了什么——您只需要知道接口,现在接口允许 null 作为返回值。

于 2013-12-24T17:21:44.053 回答
2

我在其他几个方面与他们有过这个问题。似乎他们已经对 CLR 各个部分的代码路径进行了分析。当他们发现返回 null 是可以想象的,那就是他们抱怨的时候。

在我抱怨的特定情况下, null 实际上不会发生。然而,他们将调用图追溯到一个在某些情况下可能返回 null 的方法,并且可以想象 null 值可以传播到顶部。

因此,我将其称为 ReSharper 错误(我之前认为我将其称为 CLR 错误)。

于 2009-07-02T02:56:38.417 回答
1

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

在我得到空值的情况下,我已经向我的客户发送了一个脚本来更新存储过程。我的客户的 Sql Server (2000) 设置为 DB 用户需要执行存储过程的权限。当他们更新 SP 时,权限被删除并且没有重新分配。在这种情况下,SqlCommand.ExecuteReader() 返回 null。

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

于 2011-01-18T10:20:29.720 回答
0

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

于 2021-01-27T05:27:51.710 回答