ExecuteScalar()有时会返回空对象,但不是null。为什么?

3

ExecuteScalar() 有时会返回空对象(不是 null),尽管记录存在。当我用 Quickwatch 分析此对象时,发现 object.GetType() 等于 DbNull。 我可以处理这个空对象,但我需要知道为什么有时会返回空对象,即使记录存在。

string sql = @"SELECT SentDate 
               FROM dbo.EmailOut                                    
               WHERE ID = @ID";
SqlCommand cmd = new SqlCommand(sql, _cnn);
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@ID", ID));
object obj = cmd.ExecuteScalar();
if (obj == null)
    return false
sentDate = (DateTime)obj;
cmd.Dispose();

大多数情况下,我的查询运行得很完美。请您帮忙检查一下我的代码吗?


那个“空”的对象就是null。 - Kirk Woll
3
记录可能存在,但是也有可能 SentDate 列为空吗? - Soner Gönül
希望这只是一个例子,但你应该将你的 SqlCommand 包装在一个 using 语句中。 - Squirrel5853
Sentdate列不为空。我很确定。这非常奇怪。 - cihadakt
@SecretSquirrel:一般来说,是的。在这种情况下,它并不是非常糟糕,因为SqlCommand.Dispose本质上是一个无操作。然而,我们不应该习惯于这种做法,因为例如不释放OleDbCommand或SqlCeCommand 引起麻烦。 - Heinzi
我已在Heinzi的回答下面解释原因。请查看。 - cihadakt
1个回答

9

null 的返回值表示没有找到记录。

DBNull 的返回值表示找到了一条记录,但该记录中的 SentDate 值为 NULL


但是sentdate不为空。 - cihadakt
@cihata87:这很令人惊讶。你确定吗?你能重现这个问题吗? - Heinzi
1
@cihata87:那么我们需要进一步调查。您能否准备一个最小的样本(包括数据库数据),以可靠地重现问题? - Heinzi
最后我发现记录是在1或2秒钟后创建的。但当我检查sentdate时,它为空,因为查询运行得非常快。所以我加了一句System.Threading.Thread.Sleep(2000)。现在我总能获得完整的对象了。谢谢。 - cihadakt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接