2014-07-25 2 views
0

다음 코드는 프로젝트에서 datatable 확장으로 작성한 것입니다. 그것은 실제로 효과가있었습니다. 어떤 최적화가 이루어질 수 있는지 궁금합니다. 감사. =)데이터 테이블에 NULL의 기본값을 설정하십시오.

이 질문은 어떻게 든 CR에 속해야한다고 생각합니다. 그냥 물어보십시오. 내가 입력 테이블이 Nothing 인 경우를 처리하는 것, 어느 쪽 ArgumentNullException 또는 반환을 던져 : 첫 번째 방법에 따르면

을 :

<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

입력 테이블이'Nothing' 인 경우,'ArgumentNullException'을 던지거나'True' /'False'를 반환합니다. 또한 또 다른 사소한 개선 : 나는 열 대신 행을 반복합니다. 마지막 열을 제외한 모든 열이 널이 아닌 것으로 간주하십시오. null을 감지하기 전에 모든 열의 모든 행을 반복합니다. 행을 반복하면 이미 첫 번째 행에있는 행을 확인하게됩니다 (마지막 행이 null 인 경우). –

+0

@Tim Schmelter. 응답 해 주셔서 감사합니다. 두 번째 함수에 대한 나의 의도는 null 인 각 셀의 기본값을 설정하는 것입니다. 그래서 어떻게 든 각 행과 열을 반복해야합니까? – HengChin

+0

나는 주로 첫 번째 방법을 언급했다. –

답변

2

그래서 나는 그것을 가치가 무엇인지에 대한, 여기 내 댓글을 놓을 게요 True/False

또 다른 사소한 개선 사항 : 나는 열 대신 행을 반복합니다. 마지막 열을 제외한 모든 열이 널이 아닌 것으로 간주하십시오. null을 감지하기 전에 모든 열의 모든 행을 반복합니다. 루프를 반복하면 첫 번째 행에 이미있는 행을 결정할 수 있습니다 (마지막 열이 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"" 이후. 나는 당신이 문자열을 표시하고자하는 마지막 단계와 같은 일을 할 것이다.

+0

, 감사합니다. String 값의 데이터 타입이 None 값 타입으로 분류되어 있기 때문에 GetDefaultValue 메소드에서 약간의 수정을했습니다. 더 좋은 생각이 있습니까? – HengChin

+0

@chinz : 빈 문자열로'null' 문자열을 대체하고 싶습니까? 왜? 나중에 이들을 구별 할 수 없습니다.마지막 단계에서 대체 할 것입니다. 어딘가에 표시하고 싶을 때입니다. 그렇지 않으면 문자열인지 확인하기 위해'Select Case '가 필요합니다. –

+0

내가 제대로하고 있는지 확실하지 않습니다. 내 양식에 텍스트 상자 및 레이블 컨트롤이 많이 있습니다. 내가 DataTable에서 값을 가져올 때마다 IsDBNull을 사용하여 DBNULL을 확인했습니다. 어떻게 든, 종종, 나는 아마도 하나 또는 두 개의 (새로운 컬럼이 데이터베이스에 추가되었을 때)를 생략했을 것입니다. 그래서 모든 null 값을 빈 문자열로 바꾸면 결코 잊혀지지 않을 것입니다. – HengChin

관련 문제