在datatable中设置NULL的默认值

时间:2014-07-25 09:41:13

标签: asp.net vb.net datatable

我有以下代码,我在项目中创建了数据表的扩展名。它确实有效。只是想知道是否可以通过进行任何优化。谢谢。 =)

我理解这个问题应该以某种方式属于CR。只是问一下。

<Extension()>
Public Function HasNull(ByVal dataTable As DataTable) As Boolean
    For Each column As DataColumn In dataTable.Columns
        If dataTable.Rows.OfType(Of DataRow)().Any(Function(r) r.IsNull(column)) Then
            Return True
        End If
    Next
    Return False
End Function

<Extension()>
Public Function SetDefaultForNull(ByVal dataTable As DataTable) As DataTable
    For Each row As DataRow In dataTable.Rows
        For Each col As DataColumn In dataTable.Columns
            Dim value As Object = row(col)
            If IsDBNull(value) Then
                Dim dataType As String = col.DataType.ToString

                Select Case dataType
                    Case "System.DateTime"
                        value = New DateTime
                    Case "System.Decimal", "System.Int16", "System.Int32", "System.Int64"
                        value = 0
                    Case "System.String"
                        value = String.Empty
                    Case "System.Boolean"
                        value = False
                    Case Else
                        value = 0
                End Select
                row(col) = value
            End If
        Next
    Next
    Return dataTable
End Function

1 个答案:

答案 0 :(得分:2)

所以我会在这里发表评论,以了解它的价值:

根据第一种方法: 我会处理输入表为Nothing的情况,要么抛出ArgumentNullException要么返回True / False

另一个小改进:我会循环行而不是列。考虑除了最后一列之外的所有列都是非空的。在检测到null之前,您将遍历所有列的所有行。如果你循环行,你确定已经在第一行(如果最后一列充满了空值)。

这样的事情:

<Extension()>
Public Function HasNull(dataTable As DataTable) As Boolean
    If dataTable Is Nothing Then
        Throw New ArgumentNullException("dataTable must be initialized", "dataTable")
    End If
    Dim allColumns = dataTable.Columns.Cast(Of DataColumn).ToList() ' materialize
    Dim hasNullField As Boolean = dataTable.AsEnumerable().
        Any(Function(row) allColumns.Any(Function(c) row.IsNull(c)))
    Return hasNullField
End Function

第二种方法可以使用此扩展来获取所有类型的默认值:

<Extension()>
Public Function GetDefaultValue(t As Type) As Object
    If t.IsValueType Then
        Return Activator.CreateInstance(t)
    Else
        Return Nothing
    End If
End Function

然后可以用这种方式实现第二种方法本身(将其设为Sub):

<Extension()>
Public Sub SetDefaultForNull(dataTable As DataTable)
    For Each row As DataRow In dataTable.Rows
        For Each col As DataColumn In dataTable.Columns
            If row.IsNull(col) Then
                row.SetField(col, col.DataType.GetDefaultValue())
            End If
        Next
    Next
End Sub

使用此示例数据进行测试:

Dim table As New DataTable
table.Columns.Add("ID", GetType(Int32))
table.Columns.Add("Name", GetType(String))
table.Columns.Add("Date", GetType(DateTime))
table.Rows.Add(1, "test", DateTime.Now)
table.Rows.Add(DBNull.Value, Nothing, Nothing)
table.Rows.Add(Nothing, DBNull.Value, DBNull.Value)
If table.HasNull() Then
    table.SetDefaultForNull()
End If

结果:

1       test    25.07.2014 15:05:29
0               01.01.0001 00:00:00
0               01.01.0001 00:00:00

修改:如果您真的想用空字符串替换null字符串,可以向GetDefaultValue添加参数:

<Extension()>
Public Function GetDefaultValue(t As Type, replaceNullStringsWithEmpty As Boolean) As Object
    If t.IsValueType Then
        Return Activator.CreateInstance(t)
    ElseIf replaceNullStringsWithEmpty AndAlso t = GetType(String) Then
        Return ""
    Else
        Return Nothing
    End If
End Function

但是,我不喜欢单一类型的例外情况,之后也无法区分null""。我会做你想要显示字符串的最后一步。