在对象初始值设定项中处理 DBNull

Handle DBNull in an object initializer

在我的 asp.net 网络服务中,我有一个从数据库获取数据的对象 class,但是当数据库中的某些数据为空时,我遇到了以下问题:

(1)如果我不处理数据库中的NULL值,使用如下代码:

<WebMethod> _
Public Function GetCustomerDetail(ByVal sqlQuery As String) As List(Of customerInfo)
    Dim detaillist = New List(Of customerInfo)()
    Dim detail As customerInfo

    Dim da = New SqlDataAdapter(sqlQuery, conn)
    Dim dt = New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
        detail = New customerInfo() With { _
         .CustomerID = dr("CUSTOMER_ID"), _
         .CustomerName = dr("CUSTOMER_NAME"), _
         .RegisterDate = dr("REGISTER_DATE"), _
         .Address = dr("ADDRESS") _
        }
        detaillist.Add(detail)
    Next
    Return detaillist

End Function

Public Class customerInfo
    Public CustomerID As String = String.Empty
    Public CustomerName As String = String.Empty
    Public RegisterDate As String = Date.Now.ToString("dd/MM/yyyy")
    Public Address As String = String.Empty
End Class

我收到错误:

System.InvalidCastException: 从类型 'DBNull' 到类型 'String' 的转换无效。

(2) 如果我按如下方式处理数据库中的 NULL:

<WebMethod> _
Public Function GetCustomerDetail(ByVal sqlQuery As String) As List(Of customerInfo)
    Dim detaillist = New List(Of customerInfo)()
    Dim detail As customerInfo

    Dim da = New SqlDataAdapter(sqlQuery, conn)
    Dim dt = New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
        detail = New customerInfo() With { _
         .CustomerID = dr("CUSTOMER_ID"), _
         .CustomerName = dr("CUSTOMER_NAME"), _
         .RegisterDate = dr("REGISTER_DATE"), _
         If dr("ADDRESS") = System.DBNull.Value Then
            .Address = ""
         Else
            .Address = dr("ADDRESS") _
         End if
        }
        detaillist.Add(detail)
    Next
    Return detaillist

End Function

Public Class customerInfo
    Public CustomerID As String = String.Empty
    Public CustomerName As String = String.Empty
    Public RegisterDate As String = Date.Now.ToString("dd/MM/yyyy")
    Public Address As String = String.Empty
End Class

我收到错误:

编译器错误消息:BC30985:在对象初始值设定项中初始化的字段名称或 属性 必须以“.”开头。

我想知道如何在对象初始值设定项中处理字符串和日期的 DBNull 值。

您可以使用Convert.ToString

<WebMethod> _
Public Function GetCustomerDetail(ByVal sqlQuery As String) As List(Of customerInfo)
    Dim detaillist = New List(Of customerInfo)()
    Dim detail As customerInfo

    Dim da = New SqlDataAdapter(sqlQuery, conn)
    Dim dt = New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
    Dim registerDate As Date
    If Date.TryParse(Convert.ToString(dr("REGISTER_DATE")), registerDate ) = False Then 
    'Do what you need to do if the cell is not a valid date time value
    End If
        detail = New customerInfo() With { _
         .CustomerID = Convert.ToString(dr("CUSTOMER_ID")), _
         .CustomerName = Convert.ToString(dr("CUSTOMER_NAME")), _
         .RegisterDate = registerDate.ToString("dd/MM/yyyy"), _
         .Address = Convert.ToString(dr("ADDRESS"))
        }
        detaillist.Add(detail)
    Next
    Return detaillist

End Function

根据以下 OP 的评论进行编辑。

你不能在这样的对象初始值设定项中使用 if 语句。 您必须实例化对象,然后在单独的行中设置属性。

detail = New customerInfo() 
'Then in separate lines, populate the properties individually

If dr("ADDRESS") = System.DBNull.Value Then
    detail.Address = ""
Else
    detail.Address = dr("ADDRESS") 

虽然其他方法也行,但我认为具有泛型支持的可重用扩展方法是理想的。

您可以将工作交给扩展方法并检查该值是否等于 DBNull.Value

的值
Public Module DataRowExtensions

    <System.Runtime.CompilerServices.Extension>
    Public Function GetValueOrDefault(Of TExpectedType)(dr As DataRow, propertyName As String) As TExpectedType
    If DBNull.Value.Equals(dr(propertyName)) Then
            Return Nothing
        End If

        Return DirectCast(dr(propertyName), TExpectedType)
    End Function
End Module

您可以查看此 DotNetFiddle 以查看它对各种数据类型的实际操作。

请注意扩展方法 Field<T> 确实存在并且类似,但它不处理 DBNull 值。