当使用呼叫时 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认为它可能为null,例如它允许我使用SqlCommand而不建议检查null?我猜是ExecuteReader方法有一个属性。
这是误报。
反思SqlDataReader.ExecuteReader,我可以看到读取器返回null的唯一方法是,如果内部RunExecuteReader方法为returnStream传递'false',它不是。
在SqlDataReader的深处, 一个 读者构造函数总是在某个时候被调用,所以我很确定ExecuteReader在物理上不可能返回null。
Resharper是正确的,它可以返回null潜力。
如果具体实现,则无关紧要 ExecuteReader()
不允许冒出一个空值 - 事实上,IDataReader是一个可以包含(或指向)null的对象。
- 如果您将来决定使用不同的实现,该怎么办?
IDbCommand
?
- 如果该IDbCommnd实现的下一次更新将在代码中包含一个允许冒泡null的不同流程怎么办?
您不需要知道接口实现中发生了什么,以便正确使用它 - 你只需要知道接口,现在接口允许null作为返回值。
我在其他几个方面遇到过这个问题。看起来他们已经对CLR的各个部分中的代码路径进行了分析。当他们发现可以想到返回null时,那就是他们抱怨它的时候。
在我抱怨的特定情况下,null实际上不会发生。但是,在某些情况下,它们将调用图跟踪到一个可以返回null的方法,并且可以想象空值可以传播到顶部。
所以,我称之为ReSharper错误(我之前称之为CLR错误)。
我已经确定了ExecuteReader()可以返回null的一个原因。
在我获得null的情况下,我向客户端发送了一个脚本来更新存储过程。设置了我的客户端的Sql Server(2000),以便DB用户需要权限来执行存储过程。当他们更新SP时,权限被删除而不是重新分配。在这个实例中,SqlCommand.ExecuteReader()返回null。
重新分配权限修复此问题。
我有一个问题,我查询.dbo.sysfiles的日志文件,得到了一个 null
作为回报。
我让我的客户端连接为系统管理员的SYSTEM用户,不确定发生了什么...