Muitas vezes, quando fazemos consultas a bancos de dados em aplicações .NET, obtemos como resultado um DataReader contendo os registros resultantes. Porém, geralmente é preciso obter dados de uma coluna ou linha específica, ou até mesmo informações a respeito de um campo da tabela.

Para essas situações, o mais comum e talvez o mais prático é utilizar um DataTable, que permite manipular essas informações de forma mais simples e eficiente.

Neste breve artigo será demonstrada uma forma simples de se obter um objeto DataTable a partir de um DataReader. Será criado um método que recebe como parâmetro um objeto do tipo DbDataReader, do qual descendem os DataReaders específicos de cada biblioteca, como SqlDataReader e o MySqlDataReader. Com isso, o método fica independente de qual banco de dados está sendo utilizado.

Listagem 1: Método ObterTabela em C#

public DataTable ObterTabela(DbDataReader reader)
{
    DataTable tbEsquema = reader.GetSchemaTable();
    DataTable tbRetorno = new DataTable();

    foreach (DataRow r in tbEsquema.Rows)
    {
        if(!tbRetorno.Columns.Contains(r["ColumnName"].ToString()))
        {
            DataColumn col = new DataColumn(){
                ColumnName = r["ColumnName"].ToString(),
                Unique = Convert.ToBoolean(r["IsUnique"]),
                AllowDBNull = Convert.ToBoolean(r["AllowDBNull"]),
                ReadOnly = Convert.ToBoolean(r["IsReadOnly"])
            };
            tbRetorno.Columns.Add(col);
        }
    }

    while(reader.Read())
    {
        DataRow novaLinha = tbRetorno.NewRow();
        for(int i = 0; i<tbRetorno.Columns.Count;i++)
        {
            novaLinha[i] = reader.GetValue(i);
        }
        tbRetorno.Rows.Add(novaLinha);
    }

    return tbRetorno;
}

Listagem 2: Método ObterTabela em VB.NET

Public Function ObterTabela(reader As DbDataReader) As DataTable
Dim tbEsquema As DataTable = reader.GetSchemaTable
Dim tbRetorno As DataTable = New DataTable

For Each r As DataRow In tbEsquema.Rows
     If Not tbRetorno.Columns.Contains(r("ColumnName")) Then
         Dim col As New DataColumn
         col.ColumnName = r("ColumnName").ToString
         col.Unique = Convert.ToBoolean(r("IsUnique"))
         col.AllowDBNull = Convert.ToBoolean(r("AllowDbNull"))
         col.ReadOnly = Convert.ToBoolean(r("IsReadOnly"))
         tbRetorno.Columns.Add(col)
     End If
       Next

       While reader.Read
           Dim novaLinha As DataRow = tbRetorno.NewRow
           For i As Integer = 0 To tbRetorno.Columns.Count - 1
                novaLinha(i) = reader.GetValue(i)
           Next
           tbRetorno.Rows.Add(novaLinha)
       End While

       Return tbRetorno
End Function

O DataTable resultante desse método conterá em suas colunas informações bastante úteis como o nome da coluna (fundamental), se ela aceita apenas valores únicos, se permite valores nulos e se é apenas para leitura.

Para esse método, por exemplo, poderia ser passado o resultado do método ExecuteReader do DataReader, como mostra o exemplo da Listagem 3 a seguir.

Listagem 3: Exemplo de uso do método ObterTabela em C#


SqlConnection com = new SqlConnection(“Sua string de conexão”);
SqlCommand cmd = new SqlCommand(“SELECT * FROM Tabela”, con);
try
{
	con.Open();
	DataTable tab = ObterTabela(cmd.ExecuteReader());
	meuGridView.DataSource = tab;
}
finally
{
con.Close();
}

Com o DataTable torna-se mais fácil acessar os registros, sendo possível usar laços de acesso direto às linhas e colunas (foreach) e até mesmo efetuar consultas com LINQ, enquanto com o DataReader é necessário executar um laço while para se ler todos os registros, um a um sem a possibilidade de alterá-los, posto que esta classe é utilizada apenas para leitura de dados.

Então finalizamos aqui este breve artigo, cujo objetivo é apresentar uma dica que pode ser bastante útil na manipulação de dados resultantes de uma consulta a um banco de dados em aplicações .NET.

Até a próxima oportunidade.