C# - Convertendo um DataTable para Lista de Objetos


 No artigo de hoje veremos como converter um DataTable para uma lista de objetos usando  uma abordagem bem simples na linguagem C#.

 

Um DataTable é como um container que podemos usar para armazenar informações de praticamente qualquer fonte de dados, sendo composto por uma coleção de linhas (rows) e colunas (columns)
 

 

Podemos criar um DataTable para armazenar dados em memória e realizar operações para incluir, alterar e excluir essas informações.

 

O DataTable é também um objeto central na biblioteca ADO.NET. Outros objetos que usam o DataTable incluem o DataSet e o DataView.

 

Podemos criar objetos DataTable via código adicionando linhas e colunas de acordo com nossa necessidade.

 

A classe DataTable esta presente no namespace System.Data e embora seja muito útil em muitas situações você pode desejar querer converter o seu DataTable para objetos do modelo de domínio em sua aplicação.


Essa abordagem só tem uma limitação: você tem que definir o modelo de domínio para tipar a lista de objetos.


Como exemplo vou usar o banco de dados Northwind do SQL Server e a tabela Customer.

 

Neste artigo vou mostrar como faze isso.
 

Recursos usados :

Criando o projeto no VS 2019 Community

Abra o VS 2019 Community e crie um projeto do tipo Windows Forms App(.NET Framework) via menu File -> New Project, com o nome WF_DataTable_Objetos;

A seguir incluir no arquivo form1.cs o seguintes controles a partir da Toolbox:

O leiaute da aplicação deverá esta conforme a figura abaixo:

Criando a classe para acessar o SQL Server e gerar o DataTable

Vamos criar a classe Customer que define o nosso modelo e a partir da qual iremos converter o datatable:

   public class Customer
    {
        public string CustomerID { get; set; }
        public string CompanyName { get; set; }
        public string ContactName { get; set; }
        public string ContactTitle { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public string Phone { get; set; }
        public string Fax { get; set; }
    }

Criando a classe para acessar o SQL Server e gerar o DataTable

Crie uma classe chamada AcessoDB e o método estático GetDataTable() que retorna um DataTable com o código abaixo:

using System;
using System.Data;
using System.Data.SqlClient;

namespace WF_DataTable_Objetos
{
    public class AcessoDB
    {
        private static DataTable dataTable = new DataTable();

        public static DataTable GetDataTable()
        {
             string connString = @"Data Source=MACORATTI;Initial Catalog=Northwind;Integrated            Security=True;ConnectTimeout=30;Encrypt=False;TrustServerCertificate=False; ApplicationIntent=ReadWrite;MultiSubnetFailover=False";

                string query = "select * from Customers";

                using (SqlConnection conn = new SqlConnection(connString))
                {
                    using (SqlCommand cmd = new SqlCommand(query, conn))
                    {
                        try
                        {
                            conn.Open();
                            // cria um data adapter
                            SqlDataAdapter da = new SqlDataAdapter(cmd);
                            // preenche o datatable com dados
                            da.Fill(dataTable);
                            return dataTable;
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }
        }
    }
}

Criando a classe para converter o DataTable para List

A seguir crie a classe Conversor com o método estático ConverterParaLista():

 using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace WF_DataTable_Objetos
{
    public static class Conversor
    {
        public static List<T> ConverterParaLista<T>(DataTable dt)
        {
            var columnNames = dt.Columns.Cast<DataColumn>().Select(c => c.ColumnName.ToLower()).ToList();
            var properties = typeof(T).GetProperties();
            return dt.AsEnumerable().Select(row => {
                var objT = Activator.CreateInstance<T>();
                foreach (var pro in properties)
                {
                    if (columnNames.Contains(pro.Name.ToLower()))
                    {
                        try
                        {
                            pro.SetValue(objT, row[pro.Name]);
                        }
                        catch (Exception)
                        { }
                    }
                }
                return objT;
            }).ToList();
        }
    }
}

Convertendo um DataTable para List<T>

Vamos agora testar a nossa implementação.

Os namespaces usadas no formulário são:

using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;

No início do formulário defina as variáveis :

DataTable dataTable = new DataTable();
List<Customer> listaCustomer = new List<Customer>();

No evento Click do botão de comando - Gerar DataTable - defina o código a seguir:

  private void BtnGerarDataTable_Click(object sender, EventArgs e)
   {
            try
            {
                dataTable = AcessoDB.GetDataTable();
                dgvDados.DataSource = dataTable;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
   }

Neste código estamos criando um DataTable chamado dataTable a partir dos dados da tabela Customers do banco de dados Northwind usando o método GetDataTable().

A seguir no evento Click do botão - Converter para Objetos - inclua o código abaixo:

private void BtnConverterParaObjetos_Click(object sender, EventArgs e)
  {
      try
       {
           listaCustomer = Conversor.ConverterParaLista<Customer>(dataTable);

           foreach (var customer in listaCustomer)
           {
              string dados = $"{customer.CustomerID} - {customer.ContactName} - {customer.CompanyName})";
              lvObjetos.Items.Add(dados);
           }

      }
      catch (Exception ex)
      {
             MessageBox.Show(ex.Message);
     }
}

O código acima usamos o método ConverterParaLista<>() para converter o DataTable para a lista de objetos do tipo List<Customer>.

A segsuir usamos um laço foreach para percorrer  o resultado e obter os dados. No exemplo estou exibindo apenas 3 propriedades da classe Customer.

Executando o projeto teremos o seguinte resultado:

Pegue o projeto completo aqui:  WF_DataTable_Objetos.zip

"Levando ele mesmo(Jesus) em seu corpo os nossos pecados sobre o madeiro, para que, mortos para os pecados, pudéssemos viver para a justiça; e pelas suas feridas fostes sarados."
1 Pedro 2:24


Referências:


José Carlos Macoratti