Я хочу сгенерировать некоторый отформатированный вывод данных, полученных из базы данных MS-Access и сохраненных в объекте/переменной DataTable myDataTable. Однако некоторые из полей в myDataTable cotain dbNull данных. Таким образом, следующий фрагмент кода VB.net выдаст ошибки, если значение любого из полей lastname, intials или 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, как в этот вопрос?
Единственный способ, которым я знаю, это проверить его, вы можете сделать комбинированный, если хотите, чтобы облегчить его.
If NOT IsDbNull(myItem("sID")) AndAlso myItem("sID") = sId Then
'Do success
ELSE
'Failure
End If
Я написал в VB, так как это похоже на то, что вам нужно, даже если вы смешиваете языки.
Edit
Очищено, чтобы использовать IsDbNull, чтобы сделать его более читаемым
Мне надоело справляться с этой проблемой, поэтому я написал функцию 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 я просто указывал все как объект. Но я предпочитаю универсальную версию.
Public Shared Function NotNull(Of T)(ByVal Value As T, Optional ByVal DefaultValue As T = Nothing) As T
и ее можно вызывать как If NotNull(myItem("sID")) = sID Then
или как указано выше.
Вы также можете использовать методы Convert.ToString() и Convert.ToInteger() для преобразования элементов с нулевым значением DB.
Вариант кода Стива Уортема, который будет использоваться номинально с 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
например
mynullable = GetNullable(Of Integer?)(myobj)
Затем вы можете запросить mynullable
(например, mynullable.HasValue
)
Microsoft придумала DBNull в .NET 1.0 для представления базы данных NULL. Тем не менее, это боль в использовании, потому что вы не можете создать строго типизированную переменную для хранения подлинного значения или null. Microsoft решила эту проблему в .NET 2.0 с нулевыми типами. Тем не менее, вы все еще застряли в больших кусках API, которые используют DBNull, и их нельзя изменить.
Просто предложение, но я обычно это делаю:
Если вы используете настройку 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
VB.Net
========
Dim da As New SqlDataAdapter
Dim dt As New DataTable
Call conecDB() 'Connection to Database
da.SelectCommand = New SqlCommand("select max(RefNo) from BaseData", connDB)
da.Fill(dt)
If dt.Rows.Count > 0 And Convert.ToString(dt.Rows(0).Item(0)) = "" Then
MsgBox("datbase is null")
ElseIf dt.Rows.Count > 0 And Convert.ToString(dt.Rows(0).Item(0)) <> "" Then
MsgBox("datbase have value")
End If
Для строк, содержащих строки, я могу преобразовать их в строки, как при изменении
tmpStr = nameItem("lastname") + " " + nameItem("initials")
к
tmpStr = myItem("lastname").toString + " " + myItem("intials").toString
Для сравнения в выражении if myItem ( "sID" ) = sID необходимо изменить на
myItem("sID").Equals(sID)
Затем код будет работать без каких-либо ошибок времени выполнения из-за данных vbNull.
Вы можете использовать функцию IsDbNull:
If IsDbNull(myItem("sID")) = False AndAlso myItem("sID")==sID Then
// Do something
End If
Я думаю, что это должно быть намного проще в использовании:
выберите ISNULL (сумма (поле), 0) из tablename
Скопировано из: http://www.codeproject.com/Questions/736515/How-do-I-avoide-Conversion-from-type-DBNull-to-typ
Это BY FAR самый простой способ преобразования DBNull
в строку.
Фокус в том, что вы НЕ МОЖЕТ использовать функцию TRIM
(которая была моей первоначальной проблемой) при обращении к полям из базы данных:
ПЕРЕД (вызвана ошибка msg):
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"))
Привет друзья
Это самый короткий метод для проверки db Null в DataGrid и преобразования в строку