【问题标题】:Evaluation differences between IF operator and If, then, elseIF 运算符与 If、then、else 之间的求值差异
【发布时间】:2013-11-09 00:56:05
【问题描述】:

我遇到了一个我没有预料到的情况,需要帮助回答。我们当前的系统调用 SQL 存储过程并因此创建 SQL 命令、添加参数并添加这些参数的值......比如说插入。

我们有如下代码...

cmd.Parameters.Add("@MyTimestamp", SqlDbType.DateTime)
If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = Nothing
End If

现在,当我第一次看到这个时,我有点惊讶 MyObject.MyTimestamp 曾经评估为 Nothing,但它已经存在多年没有问题。在清理工作期间,添加参数并设置其值的代码被合并,因此上面的代码变成了......

cmd.Parameters.Add("@MyTimestamp", SqlDbType.DateTime).Value = If(MyObject.MyTimestamp <> Nothing, MyObject.MyTimestamp, Nothing)

对我来说,这看起来与代码最初所做的相同,但这并不是在测试期间发现的。在测试时我收到了一个 SqlTypeException:

SqlDateTime 溢出。必须在 1753 年 1 月 1 日凌晨 12:00:00 到 9999 年 12 月 31 日晚上 11:59:59 之间。

这是因为使用 If 运算符将 MyObject.MyTimestamp 评估为不是 Nothing,它不是 Nothing 它是 DateTime.MinValue 并且它试图将其插入 sql 并且它爆炸了。原始代码的编写方式将相同的 Timestamp 评估为 Nothing (不确定如何/为什么)并且做了错误的部分。所以我的问题是有什么区别,我应该关注其他数据类型吗...?

【问题讨论】:

  • 你应该关注“Option Strict Off”..如果你打开它,你的代码会在if MyObject.MyTimestamp &lt;&gt; Nothing显示错误,因为它应该是IsNot(或Not ... Is)而不是&lt;&gt;。这不会解决你有一个值的问题,但该值不在可接受的范围内,但无论如何你都必须检查一下(应该存储在 128 字节字段中的 15MB 字符串呢?)跨度>
  • Option Strict 和 Option Explicit 在应用程序中每个代码文件的顶部都设置为 On。
  • 参数。你说的对。这就是问题所在。 DateTime 是一个值类型/结构。那些永远不可能是“无”。对他们来说,没有什么是“默认值”。一个什么都不是的整数是 0。一个 Double 是 0.0,一个 DateTime 是 ... 1.1.1 12:00 AM
  • 没错。通过进一步的测试,我认为问题不是MyObject.MyTimestamp &lt;&gt; Nothing 的评估与MyObject.MyTimestamp &lt;&gt; Datetime.MinValue 的评估相同。我认为这与我在添加参数的同时设置参数的值有关。 If 运算符和 If, Then, Else 在即时窗口中的计算结果相同。

标签: asp.net .net sql sql-server vb.net


【解决方案1】:

记住(我经常不记得)Nothing 不等同于 C# 中的 null,而更像 Default(T),以下不检查是否已设置 MyObject.MyTimestamp:

MyObject.MyTimestamp <> Nothing

但是正在准确地检查它是否是默认日期时间 (DateTime.MinValue),它大概总是这样。

另外,当你使用:

If(MyObject.MyTimestamp <> Nothing, MyObject.MyTimestamp, Nothing)

这两种返回类型(MyObject.MyTimestampNothing)必须是相同的类型,因此由于编译器知道MyObject.Timestamp 应该是一个日期时间,它不会将任何内容转换为默认日期时间。

但是,当你使用它时:

If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = Nothing
End If

它识别"@MyTimestamp" 的参数是SqlDbType.DateTime 类型,因此为此创建默认值。我不知道这是 DbNull 还是我脑海中的实际值,但无论哪种方式,它都是允许的值,因此不会引发错误。

顺便说一句,您可能希望将参数设置为DbNull.Value 而不是Nothing

If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = DbNull.Value
End If

【讨论】:

  • 好吧……就是这样! IF 运算符的返回值相同是我忽略的。我尝试使用 If 运算符逻辑,但将添加参数和设置参数值分开,我得到了同样的错误。是的,我确实希望这些为 DBNull.Value,就像它们在代码的其他区域中一样。谢谢...
猜你喜欢
  • 2012-11-25
  • 1970-01-01
  • 2011-10-08
  • 2013-05-01
  • 1970-01-01
  • 2012-08-02
  • 2021-09-18
  • 2014-06-16
  • 1970-01-01
相关资源
最近更新 更多