Obtendo um DataTable a partir de um DataReader em .NET (em C# e VB.Net)

Veja neste artigo como obter (em C# e VB.Net) um objeto DataTable a partir de um DataReader genérico, ou seja, independente de qual biblioteca/engine de conexão será utilizada.

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.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados