ADO .NET - Preenchendo um DataTable via DataReader (C#)


Neste artigo eu mostro como preencher um objeto DataTable a partir de um banco de dados SQL Server através de um DataReader a via objeto Command.

Devemos sempre considerar um DataReader quando desejamos tratar com dados de forma mais rápida mas não podemos esquecer de manter os dados na memória e também que o DataReader trabalha no modo conectado.

Neste artigo eu mostro como obter os dados a partir de um DataReader e então converter o objeto DataReader em um DataTable.

Podemos usar um objeto IDataReader para receber o objeto retornado a partir de método de um objeto Command como :  Command.ExecuteReader().

Você pode obter o esquema da tabela por um método que está disponível através da interface IDataReader, o método GetSchemaTable().

Podemos usar este método para obter o esquema da tabela que o IDataReader está tratando e então criar um novo DataTable com os dados que recebemos do esquema e começar a preenchê-lo usando os dados no DataReader.

Mas porque estamos fazendo isso mesmo ???

É uma alternativa para gerar um DataTable sem usar o Adapter.

Vamos mostrar um exemplo prático usando o Visual C# 2010 Express Edition em um projeto Windwos Forms.

Abra o Visual C# 2010 Express Edition e no menu FIle clique em New Project escolhendo o template Windows Forms Application e informando o nome DataTable_DataReader e clicando no botão OK;

Em seguida no menu Project clique em Add Class e informe o nome DAL.cs e clique em Add;

Nesta classe irei criar os métodos que usam os recursos descritos no artigo:

Devemos definir o namespace System.Data na classe para termos acesso as classes da ADO .NET.

Agora vamos criar o método chamado GetDataTableDoDataReader que cria o DataTable a partir do IDataReader conforme o código abaixo:

using System;
using System.Data;
namespace DataTable_DataReader
{
    public class DAL
    {
     /// <summary>
     /// Usa um DataReder para ler os dados de um banco de dados
     /// e preencher um DataTable
     /// </summary>
     /// <param name="dataReader"></param>
     /// <returns></returns>
     public DataTable GetDataTableDoDataReader(IDataReader dataReader)
     {
     //obtemos o esquema da tabela via DataReader
     DataTable schemaTabela = dataReader.GetSchemaTable();
     //definimos um novo objeto DataTable
     DataTable tabelaResultado = new DataTable();
     //percorremos cada linha da tabela e criamos uma nova coluna
     //definindo o nome, o tipo e os atributos ReadOnly, AutoIncrement e Unique
     foreach (DataRow dataRow in schemaTabela.Rows)
     {
        DataColumn dataColumn = new DataColumn();
        dataColumn.ColumnName = dataRow["ColumnName"].ToString();
        dataColumn.DataType = Type.GetType(dataRow["DataType"].ToString());
        dataColumn.ReadOnly = (bool)dataRow["IsReadOnly"];
        dataColumn.AutoIncrement = (bool)dataRow["IsAutoIncrement"];
        dataColumn.Unique = (bool)dataRow["IsUnique"];
        tabelaResultado.Columns.Add(dataColumn);
    }
   //lemos o datareader e preenchemos o DataTable
    while (dataReader.Read())
    {
        DataRow dataRow = tabelaResultado.NewRow();
        //percorre o DataTable e atribui os dados 
        for (int i = 0; i < tabelaResultado.Columns.Count - 1; i++)
        {
            dataRow[i] = dataReader[i];
        }
        //inclui a linha no DataTable
        tabelaResultado.Rows.Add(dataRow);
    }
    //retornamos o DataTable gerado
    return tabelaResultado;
    }
  }
}

Eu preferi comentar o código e creio que não preciso descrever como ele funciona.

Dessa forma temos uma rotina que obtém os dados via DataReader e retorna um DataTable preenchido com os dados.

Vamos agora usar o método criado e vamos aproveitar para criar um método usando o DataAdatpter no caso SqlDataAdatpter.

Primeiro temos que definir uma string de conexão no arquivo App.Config. Para criar o arquivo de configuração no menu Project clique em Add New Item e a seguir selecione o template Application Configuration FIle e aceite o nome padrão clicando em Add;

A seguir defina a string de conexão conforme mostra a figura abaixo onde iremos acessar o banco de dados Northwind.mdf do SQL Server;

Para podermos acessar o arquivo de configuração e obter a string de conexão definida temos que incluir uma referência a System.Configuration via menu Project clicando em Add Reference e na tab .NET selecionar o item desejado e clicar em OK;

Temos também de definir na classe DAL.cs os seguintes namespaces:

using System.Configuration;
using
System.Diagnostics;

Definimos também a variável para a conexão usando o objeto SQLConnection:

static SqlConnection connection;

Agora já podemos definir no construtor da classe o código que acessa o arquivo de configuração e obtém a string de conexão:

   public DAL()
   {
            string strConexaoSQL = ConfigurationManager.ConnectionStrings["conexaoSQL_Northwind"].ToString();
            connection = new SqlConnection(strConexaoSQL);
  }

Finalmente vamos definir dois métodos:

Abaixo vemos o código dos dois métodos:

 public DataTable GetDataTableViaAdapter(string consultaSQL)
     {
         connection.Open();
         DataTable dt = new DataTable();
         new SqlDataAdapter(consultaSQL, connection).Fill(dt);
         connection.Close();
         return dt;
     }
     public DataTable GetDataTableViaDataReader(string consultaSQL)
     {
         connection.Open();
         IDataReader rdr = new SqlCommand(consultaSQL, connection).ExecuteReader();
         DataTable tabelaResultante = GetDataTableDoDataReader(rdr);
         connection.Close();
         return tabelaResultante;
     }

Ambos os métodos recebem uma string contendo a instrução SQL a partir da qual os dados serão acessados e serão usados para preencher o DataTable.

No formulário form1.cs inclua um botão de comando e dois controles DataGridView conforme a figura abaixo:

Finalmente no formulário Windows Forms form1.cs inclua o seguinte código no evento Click do botão de comando:

using System;
using System.Data;
using System.Windows.Forms;
namespace DataTable_DataReader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void btnIniciar_Click(object sender, EventArgs e)
        {
            DAL dal = new DAL();
            string consulta = "Select * from Customers";
            DataTable dt1 = dal.GetDataTableViaDataReader(consulta);
            dataGridView1.DataSource = dt1;
            DataTable dt = dal.GetDataTableViaAdapter(consulta);
            dataGridView2.DataSource = dt;
            MessageBox.Show("Operação Concluida");
        }
    }
}

Executando o projeto iremos obter o seguinte resultado:

Vimos assim uma das alternativas para gerar um DataTable via código usando um DataReader usando C#.

Pegue o projeto completo aqui: DataTable_DataReader.zip

"Porque sabemos que, se a nossa casa terrestre deste tabernáculo se desfizer, temos de Deus um edifício, uma casa não feita por mãos, eterna nos céus." II Coríntios 5:1

Referências:


José Carlos Macoratti