обработка данных dbnull в vb.net

Я хочу сгенерировать некоторый форматированный вывод данных, извлеченных из базы данных MS-Access и сохраненных в объекте/переменной DataTable, myDataTable. Однако некоторые поля в myDataTable содержат данные dbNull. Таким образом, следующий фрагмент кода VB.net будет выдавать ошибки, если значение любого из полей фамилия, инициалы или sID равно dbNull.

   dim myDataTable as DataTable
   dim tmpStr as String
   dim sID as Integer = 1

   ...
   myDataTable = myTableAdapter.GetData() ' Reads the data from MS-Access table
   ...

   For Each myItem As DataRow In myDataTable.Rows

    tmpStr = nameItem("lastname") + " " + nameItem("initials")

    If myItem("sID")=sID Then
        ' Do something
    End If

    ' print tmpStr

   Next

Итак, как мне заставить приведенный выше код работать, когда поля могут содержать dbNull без необходимости каждый раз проверять, являются ли данные dbNull, как в этот вопрос?


person Azim J    schedule 21.10.2008    source источник


Ответы (11)


Единственный способ, о котором я знаю, - это проверить его, вы можете сделать комбинированный, если хотя бы упростить его.

If NOT IsDbNull(myItem("sID")) AndAlso myItem("sID") = sId Then
   'Do success
ELSE
   'Failure
End If

Я написал на VB, так как это похоже на то, что вам нужно, даже если вы смешали языки.

Изменить

Убрано использование IsDbNull, чтобы сделать его более читабельным.

person Mitchel Sellers    schedule 21.10.2008
comment
Спасибо за Ваш ответ. Я предполагаю, что это выглядит как смешанные языки из-за того, как я закодировал комментарии // вместо галочек для комментариев VB.net? - person Azim J; 21.10.2008
comment
Ага! И == в сравнении - person Mitchel Sellers; 21.10.2008
comment
Я думаю, что исправил код в вопросе как чистый код VB.Net. Спасибо за ваши ответы. - person Azim J; 21.10.2008
comment
10 лет спустя. + также. :П - person Johnny Prescott; 21.05.2017
comment
Класс DataRow имеет собственный метод IsNull. Этот код также не будет компилироваться с Option Strict On. - person jmcilhinney; 26.10.2018

Мне надоело решать эту проблему, поэтому я написал функцию NotNull(), чтобы помочь себе.

Public Shared Function NotNull(Of T)(ByVal Value As T, ByVal DefaultValue As T) As T
        If Value Is Nothing OrElse IsDBNull(Value) Then
                Return DefaultValue
        Else
                Return Value
        End If
End Function

Использование:

If NotNull(myItem("sID"), "") = sID Then
  ' Do something
End If

Моя функция NotNull() претерпела несколько изменений за эти годы. До Generics я просто указывал все как объект. Но я предпочитаю универсальную версию.

person Steve Wortham    schedule 12.11.2009
comment
+1 Работает очень хорошо, я назвал его IsNull() в соответствии с SQL Server. - person Lazlow; 05.07.2010
comment
Я предпочитаю делать вторую переменную необязательной, чтобы подпись была такой: Public Shared Function NotNull(Of T)(ByVal Value As T, Optional ByVal DefaultValue As T = Nothing) As T и ее можно было бы вызывать как If NotNull(myItem("sID")) = sID Then или как указано выше. - person Daniel; 21.01.2014
comment
У меня не работает с VS 2008: пытался использовать этот метод с созданным набором данных dataTable и не работал. NotNull(rw.computer) завершается ошибкой, поскольку код Dataset.Designer.vb пытается преобразовать его в строку перед передачей в качестве аргумента. Я полагаю, это будет работать с общим DataTable. - person D_Bester; 10.08.2016
comment
Поместите это в него при использовании значения NULL для целого числа: Public Function NotNull (ByVal value As Integer?) As Integer Return NotNull (value, 0) End Function - person Richard Griffiths; 07.10.2016
comment
Я люблю этот метод. Лаконично и эффективно. +1 - person Jessica; 02.07.2019

Вы также можете использовать методы Convert.ToString() и Convert.ToInteger() для эффективного преобразования элементов с нулевым значением DB.

person Mitchel Sellers    schedule 21.10.2008

Вариант кода Стива Уортама, который номинально используется с типами nullable:

Private Shared Function GetNullable(Of T)(dataobj As Object) As T
    If Convert.IsDBNull(dataobj) Then
        Return Nothing
    Else
        Return CType(dataobj, T)
    End If
End Function

e.g.

mynullable = GetNullable(Of Integer?)(myobj)

Затем вы можете запросить mynullable (например, mynullable.HasValue)

person Greg May    schedule 31.03.2012

Microsoft придумала DBNull в .NET 1.0 для представления базы данных NULL. Тем не менее, это боль в использовании, потому что вы не можете создать строго типизированную переменную для хранения подлинного значения или нуля. Microsoft как бы решила эту проблему в .NET 2.0 с типами, допускающими значение NULL. Однако вы по-прежнему привязаны к большим кускам API, использующим DBNull, и их нельзя изменить.

Просто предложение, но я обычно делаю так:

  1. Все переменные, содержащие данные, считываемые из базы данных или записываемые в нее, должны иметь возможность обрабатывать нулевые значения. Для типов значений это означает, что они могут быть обнулены (Of T). Для ссылочных типов (String и Byte()) это означает, что значение может быть Nothing.
  2. Напишите набор функций для преобразования туда и обратно между «объектом, который может содержать DBNull» и «переменной .NET, допускающей значение null». Оберните все вызовы API в стиле DBNull в эти функции, а затем притворитесь, что DBNull не существует.
person Christian Hayter    schedule 07.06.2009

Вы можете использовать функцию IsDbNull:

  If  IsDbNull(myItem("sID")) = False AndAlso myItem("sID")==sID Then
    // Do something
End If
person brendan    schedule 21.10.2008

Если вы используете настройку BLL/DAL, попробуйте iif при чтении объекта в DAL.

While reader.Read()
 colDropdownListNames.Add(New DDLItem( _
 CType(reader("rid"), Integer), _
 CType(reader("Item_Status"), String), _
 CType(reader("Text_Show"), String), _
 CType( IIf(IsDBNull(reader("Text_Use")), "", reader("Text_Use")) , String), _
 CType(reader("Text_SystemOnly"), String), _
 CType(reader("Parent_rid"), Integer)))
End While
person John B    schedule 05.09.2012

Для строк, содержащих строки, я могу преобразовать их в строки, как при изменении

tmpStr = nameItem("lastname") + " " + nameItem("initials")

to

tmpStr = myItem("lastname").toString + " " + myItem("intials").toString

Для сравнения в операторе if myItem("sID")=sID необходимо изменить его на

myItem("sID").Equals(sID)

Тогда код будет работать без каких-либо ошибок времени выполнения из-за данных vbNull.

person Azim J    schedule 21.10.2008

Здравствуйте, друзья

Это самый короткий способ проверить db Null в DataGrid и преобразовать в строку

  1. создайте событие проверки ячейки и напишите этот код
  2. Если Convert.ToString(dgv.CurrentCell.Value) = "" Тогда
  3. ТекущаяЯчейка.Значение = ""
  4. Конец, если
person JAY SINGH    schedule 11.08.2013

Это НАМНОГО самый простой способ преобразовать DBNull в строку. Хитрость в том, что вы НЕ МОЖЕТЕ использовать функцию TRIM (что было моей первоначальной проблемой) при обращении к полям из базы данных:

ДО (сообщение об ошибке):

Me.txtProvNum.Text = IIf(Convert.IsDBNull(TRIM(myReader("Prov_Num"))), "", TRIM(myReader("Prov_Num")))

ПОСЛЕ (больше никаких сообщений об ошибках :-)):

Me.txtProvNum.Text = IIf(Convert.IsDBNull(myReader("Prov_Num")), "", myReader("Prov_Num"))
person user3284874    schedule 07.02.2014

Я думаю, что это должно быть намного проще в использовании:

выберите ISNULL (сумма (поле), 0) из имени таблицы

Скопировано с: http://www.codeproject.com/Questions/736515/How-do-I-avoide-Conversion-from-type-DBNull-to-typ

person Sabbir Hassan    schedule 26.09.2016