SqlCommand.ExecuteReader() 啥时候返回 null?
Posted
技术标签:
【中文标题】SqlCommand.ExecuteReader() 啥时候返回 null?【英文标题】:When would SqlCommand.ExecuteReader() return null?SqlCommand.ExecuteReader() 什么时候返回 null? 【发布时间】:2021-10-11 10:01:49 【问题描述】:当使用调用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())
行带有下划线。
我的问题是阅读器对象何时会为空?我从来没有遇到过它,文档也没有提到它可能是。我应该检查它是否为 null 还是可以安全忽略?
为什么 ReSharper 会认为它可能为空,例如,它允许我使用 SqlCommand 而不建议检查它是否为空?我猜 ExecuteReader 方法上有一个属性。
【问题讨论】:
【参考方案1】:这是一个误报。
根据 SqlDataReader.ExecuteReader,我可以看到读取器返回为 null 的唯一方法是内部 RunExecuteReader 方法为 returnStream 传递了“false”,但事实并非如此。
在 SqlDataReader 的深处,总是在某个时候调用 a 读取器构造函数,所以我很确定 ExecuteReader 在物理上不可能返回 null。
【讨论】:
【参考方案2】:Resharper 是正确的,它可以返回 null。
ExecuteReader()
的特定实现是否不允许冒泡 null 值无关紧要 - 事实上,IDataReader 是一个可以包含(或指向)null 的对象。
IDbCommand
的不同实现,该怎么办?
如果该 IDbCommnd 实现的下一次更新将在代码中包含允许冒泡为 null 的不同流程怎么办?
为了正确使用接口,你不需要知道接口实现内部发生了什么 - 你只需要知道接口,现在接口允许 null 作为返回值.
【讨论】:
【参考方案3】:我在其他几个方面与他们有过这个问题。似乎他们已经对 CLR 各个部分的代码路径进行了分析。当他们发现可以返回 null 时,就会抱怨它。
在我抱怨的特定情况下,null 实际上不可能发生。但是,他们将调用图追溯到一个在某些情况下可能返回 null 的方法,并且可以想象 null 值可以传播到顶部。
所以,我称它为 ReSharper 错误(我之前以为我称它为 CLR 错误)。
【讨论】:
【参考方案4】:我已经确定了 ExecuteReader() 可以返回 null 的一个原因。
在我得到一个空值的情况下,我已经向我的客户发送了一个脚本来更新一个存储过程。我的客户的 Sql Server (2000) 设置为 DB 用户需要执行存储过程的权限。当他们更新 SP 时,权限被删除并且没有重新分配。在这种情况下,SqlCommand.ExecuteReader() 返回 null。
重新分配权限解决了这个问题。
【讨论】:
【参考方案5】:对我来说它不是 null,但在 Powershell 中查看时不会输出任何内容。 当查询没有返回任何行时,就会发生这种情况。
【讨论】:
以上是关于SqlCommand.ExecuteReader() 啥时候返回 null?的主要内容,如果未能解决你的问题,请参考以下文章
SQL 查询字符串在 SQL Server Management Studio 中有效,但在带有 SQLCommand.ExecuteReader 的 VB.net 中无效