【问题标题】:Generating a datatable from a dictionary从字典生成数据表
【发布时间】:2013-07-02 08:51:44
【问题描述】:

我目前正在开发一个 .NET WinForms 应用程序,它可以读取 8 个相同格式的 csv 文件,并将每个 CSV 文件的数据存储在一个对象中,并带有修改/检索数据的方法。

CSV 文件的每一行都有关于政策的数据。

我使用的类/对象的结构是这样的:

Policy
此类/对象存储与单个策略相关的所有数据,即 CSV 文件的一行。这个类有一个名为polData 的成员,它是一个OrderedDictionarypolData 将每个字段存储为一个字符串,其中字段标题作为键。

DataFile
此类/对象存储从 csv 文件读取的所有数据,即每个策略。这个类有一个名为polCollection 的成员,它是一个OrderedDictionarypolCollection 使用策略 ID 作为键存储所有策略对象。

对于这两个类,我都使用了OrderedDictionary,因为我需要保留将数据添加到字典中的顺序。

创建并填充这些对象后,我需要将其中一个输出到datagridview。因此,我想使用字典中的数据创建一个DataTable。请在下面找到我的方法。我的直觉是有一种更有效的方法,所以我很感激任何反馈:

DataFile类中,我有以下方法:

 Public Function toDataTable() As DataTable

    Dim dt As New DataTable
    Dim fieldHeader As String
    Dim i As Integer
    Dim pol As Policy

    '//add columns to datatable
    '//there are 68 columns. 
    '//the calcFieldHeader function returns the header string based on the header index
    For i = 0 To 67
        fieldHeader = tools.calcFieldHeader(i)
        dt.Columns.Add(fieldHeader)
    Next i

    '//loop through each policy in polCollection
    '//add policy rows to datatable
    For Each key In polCollection.keys
        pol = polCollection(key)
        dt.Rows.Add(pol.toArray)
    Next key

    Return dt

End Function

Policyclass中,我有以下方法:

 Public Function toArray() As String()
    Dim result(67) As String
    Dim inx As Integer
    inx = 0

    For Each key In polData.keys
        result(inx) = polData(key).ToString
        inx = inx + 1
    Next (key)

    Return result
End Function

【问题讨论】:

  • 您可以省去创建那些字典的步骤,将CSV数据直接移动到数据表中,使用这些数据表作为存储,而不是字典,从而避免冗余,这更“高效” .有一个 TextFieldParser 可以读取 Microsoft.VisualBasic.FileIO 命名空间中的 CSV 文件。在任何情况下,您都可以使用 DataTable 中的列来存储表示数据顺序的值。字典是不必要的。

标签: .net vb.net data-structures dictionary datatable


【解决方案1】:

您不需要使用字典。将 CSV 直接解析到数据表中。

Private Function csvToDatatable(files As List(Of String), Optional skipxLines As Integer = 0) As DataTable

    Dim vbReader As Microsoft.VisualBasic.FileIO.TextFieldParser
    Dim dt As New DataTable

    'loop through the files from the list
    For Each filePath In files

        If File.Exists(filePath) Then

            'keep track of lineCount for each file
            Dim lineCount As Integer = 1

            'setup TextFieldParser for CSV
            vbReader = New Microsoft.VisualBasic.FileIO.TextFieldParser(filePath)
            vbReader.TextFieldType = FileIO.FieldType.Delimited
            vbReader.SetDelimiters(",")

            While Not vbReader.EndOfData

                Try
                    'read each line item
                    Dim currentRow = vbReader.ReadFields()

                    'Option skip x lines incase there are header records
                    If lineCount > skipxLines Then

                        'set generic columns using count of fields
                        If dt.Columns.Count = 0 Then
                            For i = 0 To UBound(currentRow)
                                dt.Columns.Add("Column" & i.ToString)
                            Next
                        Else

                            If UBound(currentRow) <> dt.Columns.Count - 1 Then
                                'check to make sure array of fields is the same size as data columns
                                Throw New Microsoft.VisualBasic.FileIO.MalformedLineException

                            End If

                        End If
                        'add row with data from currentRow array
                        dt.Rows.Add(currentRow)

                    End If

                Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                    MsgBox("Line " & lineCount & " in file " & filePath & " is not valid and will be skipped.")
                End Try

                lineCount += 1

            End While

        End If

    Next

    Return dt

End Function

这个函数的使用看起来像这样。

Dim fileList As New List(Of String)

fileList.Add("C:\exports\texting.csv")
fileList.Add("C:\exports\texting2.csv")

theGrid.DataSource = csvToDatatable(fileList, 1)
theGrid.DataBind()

在此示例中,我假设存在标头记录。

【讨论】:

    猜你喜欢
    • 2021-01-23
    • 2016-06-28
    • 1970-01-01
    • 2014-05-17
    • 2010-11-24
    • 2020-05-25
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    相关资源
    最近更新 更多