Back-End

17 nov, 2015

C# – Trabalhando com o objeto DataTable

Publicidade

No artigo de hoje vou escrever um pouco sobre a classe DataTable, que representa uma tabela de dados na memória, mostrando como realizar as operações mais usadas com esse recurso 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 está presente no namespace System.Data.

Neste artigo, vou mostrar como realizar as seguintes operações com a classe DataTable:

  • Como criar um DataTable via código
  • Como adicionar dados em um DataTable
  • Como selecionar dados a partir de um DataTable
  • Como selecionar dados a partir de um DataTable via LINQ
  • Como percorrer um DataTable
  • Como converter um DataTable para XML
  • Como converter XML para DataTable
  • Como Converter um List para DataTable

Recursos usados: Visual Studio 2013 Express for Windows Desktop

Criando o projeto no VS 2013 Express Edition

Abra o VS 2013 Express for Windows desktop e clique em New Project. A seguir, selecione Visual C# -> Windows Forms Application.

Informe o nome Usando_DataTable e clique no botão OK.

c_dtbl11

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

  • 1 DataGridView – dgvDados

  • 1 ListBox – lbDados

  • 1 Combobox – cboCampo

  • 1 TextBox – txtCriterio

  • 8 Buttons – btnCriarDataTable, btnSelecionarDados, btnConsultaLINQ, btnConsultaLINQ_2, ConsultaLINQ_ExpressaoLambda,
    btnDataTable_XML, btnXML_DataTable e btnList_DataTable

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

c_dtbl12

No evento Click de cada botão de comando, vamos implementar a respectiva funcionalidade.

Namespaces usado no formulário:

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

Definição das variáveis dtb_Alunos e txtCaminhoArquivo no início do formulário:

DataTable dtb_Alunos;

string txtCaminhoArquivo = @"c:\dados\DataTable_XML.xml";

Criar e exibir Datatable

 private void btnCriarDataTable_Click(object sender, EventArgs e)
 {
            DataTable tabela = CriarDataTable();
            dgvDados.DataSource = tabela;
 }

O código do método CriarDataTable() é mostrado a seguir:

private DataTable CriarDataTable()
 {
            dtb_Alunos = new DataTable();
            dtb_Alunos.Columns.Add("AlunoId", typeof(int));
            dtb_Alunos.Columns.Add("Nome", typeof(string));
            dtb_Alunos.Columns.Add("Email", typeof(string));
            dtb_Alunos.Columns.Add("Telefone", typeof(string));
            dtb_Alunos.Columns.Add("Idade", typeof(int));
            dtb_Alunos.Rows.Add(1, "Macoratti", "macoratti@yahoo.com", "44669922", 45);
            dtb_Alunos.Rows.Add(2, "Jefferson", "jeff@bol.com.br", "88669977", 23);
            dtb_Alunos.Rows.Add(3, "Janice", "janjan@uol.com.br", "96885522", 20);
            dtb_Alunos.Rows.Add(4, "Jessica", "jessicalang@uol.com.br", "96885522", 25);
            dtb_Alunos.Rows.Add(5, "Miriam", "mimi@uol.com.br", "96885522", 48);
            return dtb_Alunos;
}

Neste código estamos criando um DataTable chamado dtb_Alunos com cinco colunas e a seguir adicionamos cinco linhas referente a dados de alunos: AlunoId, Nome, E-mail, Telefone e Idade.

Selecionar dados

private void btnSelecionarDados_Click(object sender, EventArgs e)
 {
            string AlunoId ="";
            string Nome="";
            string Email="";
            string Telefone = "";
            string Idade="";
            string campo = cboCampo.Text;
            string criterio = txtCriterio.Text;
            string comando;
            if (campo == "AlunoId" || campo == "Idade")
            {
                comando  = campo + "=" + criterio;
            }
            else
            {
                comando = campo + "=" + "'" + criterio + "'"; 
            }
            DataRow[] oDataRow = dtb_Alunos.Select(comando);
            foreach (DataRow dr in oDataRow)
            {
                //usei 3 sintaxes diferentes para obter os valores
                AlunoId = dr[0].ToString();
                Nome = dr["Nome"].ToString();
                Email = dr[2].ToString();
                Telefone = dr[3].ToString();
                Idade = dr.Field<int>(4).ToString();
            }
            lblSelecao.Text = AlunoId + "   " + Nome + "   " + Email + "   " + Telefone + "   " + Idade;
}

O código acima cria cinco variáveis do tipo string para receber as informações da tabela dtb_Alunos.

A seguir, montamos uma consulta composta pelo nome do campo definido na combobox – cboCampo e pelo critério definido na caixa de textotxtCriterio.

Após montar a consulta na variável comando, usamos o método Select para selecionar a linha com critério escolhido e usamos um laço foreach para percorrer  o resultado e obter os dados.

Para exibir o resultado, concatenamos os valores em um controle Label – lblSelecao.

Consultar usando LINQ

private void btnConsultaLINQ_Click(object sender, EventArgs e)
{
            //consulta usando LINQ
            IEnumerable consulta =   from aluno in dtb_Alunos.AsEnumerable()
                                               select aluno;
            foreach (DataRow dr in consulta)
            {
               lbDados.Items.Add(dr.Field<int>("AlunoId") + " - " + dr.Field<string>("Nome"));
            }
}

Para podermos realizar uma consulta LINQ em um DataTable, temos que usar o método DataTableExtensions.AsEnumerable() do namespace System.Data, que retorna um objeto IEnumerable<T>, onde o parâmetro genérico T é DataRow.

Isso é necessário pois não podemos consultar diretamente contra uma coleção de Rows de um DataTable, visto que DataRowCollection não implementa IEnumerable<T>.

Consulta LINQ (tipo anônimo)

 private void btnConsultaLINQ_2_Click(object sender, EventArgs e)
 {
            var consulta = from p in dtb_Alunos.AsEnumerable()
                               where p.Field<string>(cboCampo.Text) == txtCriterio.Text
                                select new
                               {
                                    nome = p.Field<string>("Nome"),
                                    idade = p.Field<int>("Idade"),
                                    fone = p.Field<string>("Telefone")
                               };
            lbDados.Items.Clear();
            //exibe o tipo anônimo
            foreach (var aluno in consulta)
            {
                lbDados.Items.Add(aluno.nome + "   " + aluno.idade + "  " + aluno.fone);
            }
 }

Nesta consulta LINQ estamos criando um tipo anônimo (nome, idade e fone) com base em uma consulta montada com os valores selecionados nos controles cboCampo e txtCriterio.

Expressão Lambda

private void ConsultaLINQ_ExpressaoLambda_Click(object sender, EventArgs e)
     {
            var consulta = from aluno in dtb_Alunos.AsEnumerable()
                              select aluno;
            IEnumerable alunos = consulta.Where(c => c.Field<string>("Nome").Contains("J"));
            lbDados.Items.Clear();
            //Todos os nomes que contem "J"
            foreach (DataRow aluno in alunos)
            {
                lbDados.Items.Add(aluno.Field<string>("Nome"));
            }
    }

Nesta consulta LINQ, usamos uma expressão lambda para obter os nomes que contém a letra J.

DataTable => XML

private void btnDataTable_XML_Click(object sender, EventArgs e)
  {
            try
            {
                dtb_Alunos.TableName = "Alunos";               
                dtb_Alunos.WriteXml(txtCaminhoArquivo);
                MessageBox.Show("Arquivo XML gerado com sucesso");
                System.Diagnostics.Process.Start(txtCaminhoArquivo);
            }
            catch(Exception ex)
            {
                MessageBox.Show("Erro : " + ex.Message);
            }
}

Para gerar um XML a partir do Datatable usamos o método WriteXML() passando o caminho e nome do arquivo xml.

XML => DataTable

private void btnXML_DataTable_Click(object sender, EventArgs e)
    {
            try
            {
                dtb_Alunos.ReadXml(txtCaminhoArquivo);
                dgvDados.DataSource = dtb_Alunos;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro : " + ex.Message);
            }
  }

Para converter de XML para DataTable apenas usamos o método ReadXml() informando o caminho e nome do arquivo xml.

List => DataTable

private void btnList_DataTable_Click(object sender, EventArgs e)
  {
            // Examplo de lista : seleções da copa américa
            List<string[]> oLista = new List<string[]>();
            oLista.Add(new string[] { "Brasil", "Peru", "Venezuela" , "Colômbia" });
            oLista.Add(new string[] { "Argentina", "Paraguai", "Uruguai", "Jamaica" });
            oLista.Add(new string[] { "Chile", "Bolívia", "México", "Equador" });
            // Converte para DataTable
            DataTable oDataTable = ConverteLista_DataTable(oLista);
            dgvDados.DataSource = oDataTable;
 }

O código acima cria uma lista de strings contendo as seleções da copa América. A seguir, chamamos o método ConverteLista_DataTable() passando a lista criada e exibimos o DataTable retornado no DataGridView.

O código do método ConverteLista_DataTable é dado a seguir:

private DataTable ConverteLista_DataTable(List<string[]> oLista)
 {
            // Nova tabela
            DataTable oDataTable = new DataTable();
            // no maximo colunas
            int colunas = 0;
            foreach (var array in oLista)
            {
                if (array.Length > colunas)
                {
                    colunas = array.Length;
                }
            }
            // Adiciona colunas
            for (int i = 0; i < colunas; i++)
            {
                oDataTable.Columns.Add();
            }
            // Adiciona linhas
            foreach (var array in oLista)
            {
                oDataTable.Rows.Add(array);
            }
            return oDataTable;
}

Executando o projeto e selecionando a guia HTML para XAML e colando um trecho de código HTML conforme abaixo:

c_dtbl13

Pegue o projeto completo aqui: Usando_Datatable.zip