C#
- Usando DataTableReader com Windows Forms
O DataSet pode ser considerado o principal objeto das aplicações centrada em dados da tecnologia ADO .NET e contém uma representação do banco de dados em memória, representado por uma coleção de tabelas com seus relacionamentos e restrições.
Veja abaixo uma figura representando o DataSet no namespace System.Data da arquitetura ADO .NET :
![]() |
O problema do dataset é que ele pode ser lento dependendo da situação e a maneira como você o esta manipulando.
Um DataReader (SqlDataReader/OledbDataReader) é muito mais rápido que um DataSet e consome menos memória mas o grande problema do DataReader é que ele sempre requer uma conexão ativa, e, para usá-lo temos que fechar a conexão.
Não haveria uma forma mais rápida
de tratar dados ? Sim, seus problemas acabaram , use o DataTableReader
...
Um DataTableReader obtém o conteúdo de um ou mais de um objeto DataTable na forma de um conjunto de dados somente leitura de acesso sequencial.
Ele é uma combinação de um DataTable e um DataReader :
- Em um DataTable podemos armazenar uma única tabela de um banco de dados com todas as constraints no modo desconectado e podemos efetuar toda a manipulação de dados com ele;
- Um DataReader pode conter uma única tabela de registros, com dados somente leitura de acesso sequencial e para isso precisamos ter um conexão aberta com o banco de dados, dai não podemos efetuar a manipulação dos dados.
Pois o DataTableReader juntou o melhor dos dois mundos: ele pode conter mais do que um DataTable em um modo desconectado como um conjunto de dados somente leitura de acesso sequencial.
A classe DataTableReader foi desenvolvida de forma a trabalhar no modo desconectado. A iteração nas linhas é feita a partir do cache. Os dados no cache podem ser modificados enquanto o DataTableReader esta ativo.
Criando um DataTableReader
Obs: No exemplo deste artigo eu estou acessando o banco de dados Agenda.mdf criado no Management Studio e a tabela Clientes que possui os campos : id, nome e email. Para saber mais acessa o meu artigo : Usando o SQL Server Management Studio
Abra o Visual C# 2008 Express Edition (podemos usar também o SharpDevelop 3.0) e crie um novo projeto com o nome U_DataTableReader;
A seguir inclua no formulário padrão form1.cs , a partir da ToolBox, os controles :
A seguir inclua na primeira TabPage o controle ListBox e na segunda TabPage o controle DataGridView conforme abaixo:
![]() |
![]() |
Um DataTableReader pode ser criado a partir de qualquer DataTable através do método CreateDataReader. Vejamos um exemplo:
Coloque o código abaixo no evento Click do item ListBox do Menu Carregar:
void ListBoxToolStripMenuItemClick(object sender, EventArgs e) { string sql = "Select * from Clientes"; string strconn = @"Data Source=.\SQLEXPRESS;Initial Catalog=Agenda;Integrated Security=True"; SqlDataAdapter da = new SqlDataAdapter(sql, strconn); DataTable dt = new DataTable(); da.Fill(dt); DataTableReader dtr = dt.CreateDataReader(); if (dtr.HasRows) { while (dtr.Read()) { lstb_Resultado.Items.Add(dtr["nome"].ToString()); } } else { MessageBox.Show("Não há dados"); } } |
Execute o projeto e clique no item ListBox do menu Carregar:
![]() |
Exibindo um DataTableReader em controles de grid
Uma outra característica da classe DataTableReader é que podemos usá-la como uma fonte de dados para popular um DataSet ou DataTable e em seguida exibir o resultado em um controle de Grid como DataGridView ou GridView.
Fazemos isso usando o método Load do DataTableReader.
O método Load preenche um DataTable com os valres a partir de uma fonte de dados usando a interface IDataReader. Se o DataTable já contiver linhas os dados oriundos da fonte de dados serão mesclados com as linhas existentes de acordo com o valor do parâmetro LoadOption o qual pode ser:
Load option | comportamento |
---|---|
OverwriteChanges | Os valores de entrada para essa linha serão gravados tanto no valor atual e nas versões de valor original dos dados para cada coluna. |
PreserveChanges | Os valores de entrada para essa linha serão gravados à versão original do valor de cada coluna. A versão atual dos dados em cada coluna não será alterado. Este é padrão. |
Upsert | Os valores de entrada para essa linha serão gravados para a versão atual de cada coluna. A versão original de dados de cada coluna não será ser Alterado. |
O método Load consome o primeiro conjunto de registro a partir da IDataReader carregada, e após isso defina posição do leitor para o próximo conjunto de registros se houver. Este método leva em consideração 3 aspectos específicos quando esta carregando dados a partir de uma instância IDataReader:
Quando estiver trabalhando como esquema o método Load pode encontrar as seguintes condições:
Condição | Comportamento |
---|---|
O DataTable não possui um esquema. | O método Load infere o esquema baseado no conjunto de registros a partir da IDataReader importada. |
O DataTable possui um esquema incompatível com o esquema carregado. | O método Load lança um exceção correspondente a um erro particular que ocorre quando vai tentar carregar os dados no esquema incompatível. |
Os esquemas são compatíveis mas o conjunto de registros carregado contém colunas que não existem no DataTable. | O método Load inclui uma coluna extra ao esquema do DataTable. O método lança uma exceção se as colunas contiverem valores compatíveis. O método também retorna a informação da constraint a partir do conjunto de registros para todas as colunas incluídas. |
O esquemas são compatíveis mas o conjunto de registros carregado contém menos colunas que o DataTable. | Se a coluna que faltar possuir um valor padrão ou o tipo da coluna de dados for nullable, o método permite que linhas sejam incluídas substituindo as linhas padrão ou os valores nulos para a coluna em falta. |
Você deve considerar também que cada linha no DataTable mantém tanto o valor atual e o valor original para cada coluna.
Se a linha existente e a linha que esta sendo carregada contiverem valores de chave primária, a linha é processada usando o seu valor atual, de outra forma ela é tratada como uma nova linha.
Em termos de eventos , o evento RowChanging ocorre antes de cada linha ser alterada, e o evento RowChanged ocorre depois que cada linha foi alterada. Em cada caso, a propriedade Action da instância DataRowChangedEventArgs passada para o manipulador de eventos contém a informação sobre a ação particular associada com o evento.
Vejamos um exemplo:
Coloque o código a seguir no evento Click do item DataGridView do menu Carregar:
void DataGridViewToolStripMenuItemClick(object sender, EventArgs e) { DataSet ds = new DataSet(); string sql = "Select * from Clientes"; string strconn = @"Data Source=.\SQLEXPRESS;Initial Catalog=Agenda;Integrated Security=True"; SqlDataAdapter da = new SqlDataAdapter(sql, strconn); DataTable dtClientes = new DataTable(); da.Fill(dtClientes); ds.Tables.Add(dtClientes); DataTableReader dtr = new DataTableReader(ds.Tables[0]); dtClientes.Load(dtr, LoadOption.OverwriteChanges); gdv_Resultado.DataSource = dtClientes; } |
Executando o projeto e clicando na opção do menu iremos obter:
![]() |
E é isso ai. Muitas vezes temos um recurso importante a nossa disposição e não o usamos por falta de informação, Fica aqui o registro.
Pegue o projeto completo aqui:
U_DataTableReader.zip (sem a base de
dados)
Aguarde mais artigos sobre ADO .NET com C#.
Eu sei é apenas C#, mas eu gosto...
Referências:
http://msdn.microsoft.com/pt-br/library/system.data.loadoption.aspx
José Carlos Macoratti