dBNull.value 和 is 运算符



我正在将 VB2005 Web 应用程序移植到 VB2008,但在编译它时遇到了问题。

当我尝试编译项目时,问题是由我引起的,我收到此错误:

If m Is DBNull.Value...

错误:

'Is' operator does not accept operands of type 'Integer'. 
Operands must be reference or nullable types.

法典:

Public Shared Function getNextID(ByVal t As String, ByVal f As String)
        Dim m = 0
        Dim c As New Data.SqlClient.SqlConnection
        c = getConn()
        c.Open()
        Dim s As String
        s = "SELECT MAX(" & f  & ")AS max FROM " & t
      Dim q As New Data.SqlClient.SqlCommand(s, c)
        Dim r = q.EmecuteReader
        While r.Read
            m = r.GetValue(0)
        End While
        If m Is DBNull.Value Then
            m = 1
        Else
            m += 1
        End If
        r = Nothing
        q = Nothing
        c.Close()
        c = Nothing
        Return m
End Function

有没有办法允许此功能在不更改它的情况下运行?如果没有,我将如何解决它?

您的问题是以下行:

Dim m = 0

我怀疑它在VS2005中工作的原因是因为Option Strict被关闭了,所以m的类型默认为Object。 换句话说,在VS2005中,对于Option Strict Off,上面的行将等效于:

Dim m As Object = 0

如果m是一个对象,则它引用的任何值都将被装箱,因此将允许Is操作。 但是,在您的VS2008项目中,我怀疑Option Infer已打开(该功能在2005年不存在),因此m的类型在编译时被推断为Integer,因为您将其设置为整数文字(Dim m = 0)。 换句话说,在VS2008中,Option Infer On上述行将等效于:

Dim m As Integer = 0

由于它被声明为Integer类型,而不是Object类型,因此您不能再使用Is运算符。 有关此内容的详细信息,请参阅 MSDN 的此页,其中给出了此示例:

点心数量 = 5

  • 如果选项推断处于打开状态(默认值),则变量采用初始值设定项的数据类型。请参阅本地类型推断 (Visual Basic)。
  • 如果"选项推断"处于关闭
  • 状态,而"选项严格"处于关闭状态,则该变量将采用"对象"的数据类型。
  • 如果"选项推断"处于关闭状态,而"选项严格"处于打开状态,则会发生编译时错误。

解决此问题的最简单方法是简单地打开Option Infer Off,以便它以与VS2005相同的方式编译。 但是,如果要保留Option Infer On并改为修复代码,则需要指定变量类型,如下所示:

Dim x As Object = 0

您可能认为可以通过更改检查是否m Is DBNull的方式来修复它。 例如,将编译以下任一行:

If Convert.IsDBNull(m) Then

或:

If TypeOf m Is DBNull Then

但是,您会注意到这两个If语句都不会计算为 true。如果m被声明为Integer,那么它就永远不能被DBNull。 如果数据库中的列等于 null,则以下行将引发异常,因为它会尝试将DbNull对象强制转换为不可能Integer

m = r.GetValue(0) ' This will throw exception if column is null and m is an integer

m变量支持等于IntegerDbNull对象的唯一方法是将其声明为 Object

如果项目有许多未指定类型的地方,例如,则应关闭 Option Infer 。 如果要查找所有出现问题的地方,以便可以在代码中将它们全部修复,然后重新打开Option Infer,可以暂时打开Option Infer Off并打开Option Strict On。 当 Option Strict 打开且Option Infer关闭时,除非始终指定所有变量类型,否则项目将不会编译。

您可以使用类似以下内容在数据库查询阶段消除该问题

SELECT COALESCE(MAX(" & f & "), 0) AS max FROM " & t

然后无条件地递增 m。

此外,您可以使用ExecuteScalar而不是ExecuteReader,因为您只得到一个值。

只需使变量 m nullabale

  Dim m As Nullable(Of  Integer)

最新更新