VB .NET - Convertendo List para DataTable e vice-versa


Hoje vou mostrar como podemos converter um DataTable para List e vice-versa usando a linguagem VB .NET.

Neste artigo você vai aprender a :

Requisitos:

Objetivos

Converter um DataTable para List e vice-versa. Iremos exibir os dados em um controle DataGridView usando a sua propriedade DataSource.

Criando o projeto no Visual Studio 2012 Express for desktop

Abra o Visual Studio 2012 Express for desktop e clique em New Project;

A seguir selecione o template Windows Forms Application, informe o nome DataTable_List e clique em OK;

A seguir vamos incluir a partir da Toolbox os seguintes controles no formulário form1.vb:

Disponha os controles conforme o leiaute abaixo:

Vamos definir uma classe que irá representar um Cliente definindo nesta classe 4 propriedades que irão representar o nosso domínio.

No menu PROJECT clique em Add Class;

A seguir selecione o template Class, informe o nome Cliente.vb e clique no botão Add e a seguir defina o seguinte código nesta classe:

Public Class Cliente

    Public Property ClienteId As Integer
    Public Property Nome As String
    Public Property Email As String
    Public Property Idade As System.Nullable(Of Integer)

End Class

A seguir vamos incluir uma nova classe no projeto que deverá conter o código para realizar a conversão.

No menu PROJECT clique em Add Class;

A seguir selecione o template Class, informe o nome Conversor.vb e clique no botão Add e a seguir defina o seguinte código nesta classe:

mports System.Reflection

Public Class Conversor

    Public Function ConverterListParaDataTable(Of T)(items As List(Of T)) As DataTable

        Try
            Dim dataTable As New DataTable(GetType(T).Name)
            'Pega todas as propriedades
            Dim Propriedades As PropertyInfo() = GetType(T).GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)
            For Each _propriedade As PropertyInfo In Propriedades
                'Define os nomes das colunas como os nomes das propriedades
                dataTable.Columns.Add(_propriedade.Name)
            Next
            For Each item As T In items
                Dim valores = New Object(Propriedades.Length - 1) {}
                For i As Integer = 0 To Propriedades.Length - 1
                    'inclui os valores das propriedades nas linhas do datatable
                    valores(i) = Propriedades(i).GetValue(item, Nothing)
                Next
                dataTable.Rows.Add(valores)
            Next
            Return dataTable
        Catch ex As Exception
            Throw ex
        End Try
    End Function
End Class

O método ConverterListParaDataTable() recebe uma lista de itens de um tipo definido, nosso caso o tipo é a classe Cliente, e usando Reflection converte a lista para um objeto DataTable.

Para criar a lista de itens que representam uma coleção de objetos Cliente vamos definir a rotina CriarDados() no evento Load do formulário:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        criarDados()
End Sub

O código da rotina criarDados() deverá criar uma lista de objetos Cliente conforme abaixo:

 Private Sub criarDados()
        Clientes = New List(Of Cliente)() From { _
            New Cliente() With {.ClienteId = 100, .Nome = "Macoratti", .Email = "macoratti@yahoo.com", .Idade = 45}, _
            New Cliente() With {.ClienteId = 200, .Nome = "Jefferson", .Email = "jeffbol@bol.com.br", .Idade = 19}, _
            New Cliente() With {.ClienteId = 300, .Nome = "Janice", .Email = "janjan@uol.com.br", .Idade = 18}, _
            New Cliente() With {.ClienteId = 400, .Nome = "Jessica", .Email = "jessica@gmail.com.br", .Idade = 23}, _
            New Cliente() With {.ClienteId = 500, .Nome = "Miriam", .Email = "mimi@bol.com.br", .Idade = 35} _
    }
    End Sub

Finalmente podemos definir o código no evento Click do botão - Converter para DataTable - que irá converter a lista para um DataTable e exibir os dados no DataGridView:

    Private Sub btnDataTable_Click(sender As Object, e As EventArgs) Handles btnDataTable.Click
        Try
            Dim conv As New Conversor
            dgvResultado.DataSource = conv.ConverterListParaDataTable(Clientes)
        Catch ex As Exception
            MessageBox.Show("Erro : " & ex.Message)
        End Try
    End Sub

O resultado obtido pode ser visto abaixo:

Convertemos assim a nossa lista de clientes para um DataTable.

Convertendo um DataTable para uma Lista

Para converter um DataTable para uma lista vamos criar um DataTable manualmente. Precisamos definir também a classe que representará o tipo da lista gerada.

No formulário form1.vb vamos criar a rotina criarTabela() que cria uma tabela ContatosDataTable que possui a seguinte estrutura :

Abaixo temos o código da rotina criarTabela:

 Private Sub criarTabela()

        ContatosDataTable = New DataTable("Contatos")
        Dim dc As DataColumn

        dc = New DataColumn
        With dc
            .DataType = GetType(Integer)
            .ColumnName = "ContatoId"
        End With

        ContatosDataTable.Columns.Add(dc)
        ContatosDataTable.Columns.Add(New DataColumn("Nome"))
        ContatosDataTable.Columns.Add(New DataColumn("Endereco"))
        ContatosDataTable.Columns.Add(New DataColumn("Cidade"))
        ContatosDataTable.Columns.Add(New DataColumn("Cep"))

        ContatosDataTable.Rows.Add(10, "Macoratti", "Rua Projetada, 100", "Brasilia", "78900-500")
        ContatosDataTable.Rows.Add(10, "Janice", "Rua Mirassol, 12", "Lins", "17560-500")
        ContatosDataTable.Rows.Add(10, "Jefferson", "Pça XV Novembro, 509", "Santos", "11900-300")
        ContatosDataTable.Rows.Add(10, "Macoratti", "Av. Peru, 980", "Bauru", "13900-520")

    End Sub

Temos que criar uma classe que representa um contato com base na estrutura da tabela criada acima:

No menu PROJECT clique em Add Class;

A seguir selecione o template Class, informe o nome Contato.vb e clique no botão Add e a seguir defina o seguinte código nesta classe:

Public Class Contato

    Public Property ContatoId As Integer
    Public Property Nome As String
    Public Property Endereco As String
    Public Property Cidade As String
    Public Property Cep As String

End Class

Agora vamos abrir o arquivo Conversor.vb e definir o código para converter o DataTable para List.

Vamos criar 3 novos métodos na classe Conversor:

  1. ConverteDataTableParaLista(Of T)(tabela as DataTable) As List(Of T) - Converte um DataTable para uma lista do tipo T definida no nosso exemplo como sendo a classe Contato; Utiliza o método ConverDataRowParaLista;
  2. ConvertDataRowParaLista(Of T)(tabela as DataTable) As List(Of T) - Retorna uma lista de linhas convertidas a partir de datarow; Chama o método CriaItem;
  3. CriaItem - Converte um DataRow para um objeto do tipo T (no exemplo T é do tipo Contato)

A seguir temos o código para esses três métodos inseridos na classe Conversor:

 Public Shared Function ConverteDataTableParaLista(Of T)(tabela As DataTable) As IList(Of T)
        If tabela Is Nothing Then
            Return Nothing
        End If
        Dim linhas As New List(Of DataRow)()
        For Each row As DataRow In tabela.Rows
            linhas.Add(row)
        Next
        Return ConvertDataRowParaLista(Of T)(linhas)
    End Function

    Public Shared Function ConvertDataRowParaLista(Of T)(linhas As IList(Of DataRow)) As IList(Of T)
        Dim lista As IList(Of T) = Nothing
        If linhas IsNot Nothing Then
            lista = New List(Of T)()
            For Each linha As DataRow In linhas
                Dim item As T = CriaItem(Of T)(linha)
                lista.Add(item)
            Next
        End If
        Return lista
    End Function


    Public Shared Function CriaItem(Of T)(row As DataRow) As T
        'converte um DataRow para um objeto T
        Dim nomeDaColuna As String
        Dim objeto As T = Nothing
        If row IsNot Nothing Then
            objeto = Activator.CreateInstance(Of T)()
            For Each coluna As DataColumn In row.Table.Columns
                nomeDaColuna = coluna.ColumnName
                'Pega a propriedade com a mesma coluna
                Dim prop As PropertyInfo = objeto.[GetType]().GetProperty(nomeDaColuna)
                Try
                    'Pega o valor da coluna
                    Dim value As Object = If((row(nomeDaColuna).[GetType]() = GetType(DBNull)), Nothing, row(nomeDaColuna))
                    'Define o valor da propriedade
                    prop.SetValue(objeto, value, Nothing)
                Catch
                    Throw
                End Try
            Next
        End If
        Return objeto
    End Function

No evento Click do botão de comando - Converter DataTable para List - inclua o código a seguir:

  Private Sub btnList_Click(sender As Object, e As EventArgs) Handles btnList.Click
        criarTabela()
        Try
            Dim lista As IList(Of Contato) = Conversor.ConverteDataTableParaLista(Of Contato)(ContatosDataTable)
            dgvResultado.DataSource = lista
        Catch ex As Exception
            MessageBox.Show("Erro :" & ex.Message)
        End Try
    End Sub

Executando o projeto e clicando neste botão teremos o resultado a seguir:

Pegue o projeto completo aqui: DataTable_List.zip

João 12:46 Eu, que sou a luz, vim ao mundo, para que todo aquele que crê em mim não permaneça nas trevas.

Referências:


José Carlos Macoratti