dBNull.value и оператор

Я переношу веб-приложение VB2005 на VB2008 и сталкиваюсь с задачами его компиляции.

Проблема возникает, когда я пытаюсь скомпилировать проект, я получаю эту ошибку в строке:

Если 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

Есть ли способ разрешить это функционирование без его изменения? А если нет, как бы исправить это?

1
nl ja de

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 выводится в compile- чтобы быть Integer , потому что вы устанавливаете его равным целочисленному литералу ( Dim m = 0 ). Другими словами, в VS2008 с Option Infer On приведенная выше строка будет эквивалентна:

Dim m As Integer = 0

Поскольку он объявлен как тип Integer , а не тип Object , вы больше не можете использовать оператор Is . Более подробную информацию об этом можно найти на этой странице в MSDN, где этот пример приведен:

Dim qty = 5

     
      
  • Если опция Infer включена (по умолчанию), переменная принимает тип данных инициализатора. См. Локальный запрос типа (Visual Basic).
  •   
  • Если параметр Infer выключен, а параметр Strict отключен, переменная принимает тип данных объекта.
  •   
  • Если параметр Infer выключен и опция Strict включена, возникает ошибка времени компиляции.
  •   

Самый простой способ исправить проблему - просто повернуть 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 . Если столбец в базе данных когда-либо равнялся нулю, следующая строка выдавала бы исключение, потому что оно попыталось бы превратить объект DbNull в Integer , что невозможно:

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

Единственный способ для переменной m поддерживать равномерный объект Integer или DbNull , если он был объявлен как Object код>.

Если в проекте много мест, где не указан тип, например, вы должны отключить Option Infer . Если вы хотите найти все места, где это проблема, чтобы вы могли исправить их все в коде, а затем снова включите Option Infer , вы можете временно включить Option Infer Выключить и повернуть Option Strict On . Когда Option Strict включен и Option Infer выключен, проект не будет компилироваться, если не будут указаны все типы переменных.

3
добавлено

Вы можете устранить проблему на этапе запроса базы данных с чем-то вроде

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

а затем безоговорочно увеличивайте m.

Кроме того, вы можете использовать ExecuteScalar вместо ExecuteReader, поскольку вы получаете только одно значение.

0
добавлено

Просто сделайте переменную m nullabale

  Dim m As Nullable(Of  Integer)
0
добавлено
DotNetRuChat
DotNetRuChat
2 992 участник(ов)

Чат русскоязычного .NET сообщества http://dotnet.ru/ Вам могут быть интересны: @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @xamarin_russia, @microsoftstackjobs, @uwp_ru Флуд в @dotnettalks

Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

pro.net
pro.net
710 участник(ов)

Обсуждение .NET Framework и всего, что с ним связано. Правила: не флудить не по теме, уважать ваших коллег и никакой рекламы (объявления о вакансиях можно согласовать с @AlexFails). Флудилка: @dotnettalks Участник @proDOT

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot

.NET Talks: Force Push Masters
.NET Talks: Force Push Masters
490 участник(ов)

Свободный чат .NET разработчиков. Правила: t.me/dotnettalks/56823 Вам могут быть интересны: @dotnetruchat, @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @dotnetgroup, @xamarin_russia, @microsoftstackjobs, @uwp_ru http://combot.org/chat/-1001128250813

.NET Chat Убежище
.NET Chat Убежище
246 участник(ов)

Чат .NET разработчиков под эгидой MSK/SPB .NET Community Group Вам могут быть интересны: @fsharp_chat, @dotnetruchat, @cilchat, @xamarin_russia, @microsoftstackjobs, @dotnetgroup Флуд в @dotnettalks

.NET CIL Chat
.NET CIL Chat
54 участник(ов)

.NET CIL (aka IL aka MSIL)