我有以下代码,我在项目中创建了数据表的扩展名。它确实有效。只是想知道是否可以通过进行任何优化。谢谢。 =)
我理解这个问题应该以某种方式属于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
答案 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
和""
。我会做你想要显示字符串的最后一步。