dBNull.value并且是运算符

时间:2013-01-29 02:32:36

标签: vb.net visual-studio-2008 operator-keyword dbnull

我正在将一个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

有没有办法让这个功能在不改变的情况下运行?如果没有,我该如何解决?

3 个答案:

答案 0 :(得分:3)

您的问题如下:

Dim m = 0

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

Dim m As Object = 0

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

Option Infer On

由于它被声明为Dim m As Integer = 0 类型而不是Integer类型,因此您不能再使用Object运算符了。有关此内容的更多信息可以在MSDN的this page上找到,其中给出了此示例:

  

Dim qty = 5

     
      
  • 如果启用了Option Infer(默认值),则变量将采用初始化程序的数据类型。请参阅本地类型推断(Visual Basic)。
  •   
  • 如果Option Infer关闭且Option Strict关闭,则变量采用Object的数据类型。
  •   
  • 如果Option Infer已关闭且Option Strict已启用,则会发生编译时错误。
  •   

解决问题的最简单方法是简单地转动Is,使其以与VS2005相同的方式进行编译。但是,如果您要离开Option Infer Off,而是修改代码,则需要指定变量类型,如下所示:

Option Infer On

您可能认为可以通过更改检查Dim x As Object = 0 的方式来解决此问题。例如,以下任一行都将编译:

m Is DBNull

或者:

If Convert.IsDBNull(m) Then

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

Integer

m = r.GetValue(0) ' This will throw exception if column is null and m is an integer 变量支持等于mInteger对象的唯一方法是将其声明为DbNull

如果项目有很多没有指定类型的地方,就像这样,你应该关闭Object。如果您想找到问题所在的所有地方,以便您可以在代码中修复所有问题,然后重新启用Option Infer,则可以暂时转为Option Infer并转为{{ 1}}。当Option Infer Off打开且Option Strict On关闭时,除非始终指定所有变量类型,否则项目将无法编译。

答案 1 :(得分:0)

您可以使用类似

的方法消除数据库查询阶段的问题
SELECT COALESCE(MAX(" & f & "), 0) AS max FROM " & t

然后无条件地增加m。

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

答案 2 :(得分:0)

只需将你的变量设为nullabale

  Dim m As Nullable(Of  Integer)