Desenvolvimento - C#

Trabalhando com dados desconectados – WinForms – C#

A ADO.NET vai um pouco além da interação de uma aplicação com um fonte de dados, ela traz o grande diferencial frente aos modelos passados de conexão a base de dados que possibilitam a manipulação da informação de forma desconectada.

por Rodrigo S. Donini



A ADO.NET vai um pouco além da interação de uma aplicação com um fonte de dados, ela traz o grande diferencial frente aos modelos passados de conexão a base de dados que possibilitam a manipulação da informação de forma desconectada.

Desconectada? – É simples, uma vez que a aplicação acessa a fonte de dados, traz os dados para ela, desconecta-se, e processa-os localmente, sem manter o tráfego entre fonte de dados e aplicação.

Figura 01: Tráfego de dados entre aplicação cliente e fonte de dados

Na figura 01 podemos ver a seqüência de requisição dos dados, este é um recurso fácil de usar e muito útil para quem necessita trabalhar com dispositivos móveis e não está sempre conectado na rede.

Em nosso modelo iremos construir uma agenda de contatos, com funcionalidades bastante simples, trabalharemos de forma desconectada, armazenando dados dentro de um documento xml, e para fazer o controle desses registros iremos criar o esqueleto da tabela desses dados, mas não se preocupe, com base na construção da tabela a ADO.NET irá criar o Schema dela automaticamente, acompanhe na Figura 02 a interface do protótipo.

Neste exemplo buscaremos os dados diretamente do xml citado acima, mas eles também poderiam vir de uma fonte de dados qualquer, como uma base de dados, um arquivo texto e por aí vai.

Faça download do fonte: ADO.NET_Disconnected_Data.zip.

Figura 02: Interface do exemplo

O que foi usado para montar este exemplo?

Montei este exemplo usando Visual Studio 2005, .Net Framework 2.0, a linguagem escolhida foi C# e a arquitetura escolhida foi WinForms, mas poderia ter sido feito em WebForms, e qualquer outra linguagem suportada pelo VS.Net e .Net Framework.

Como já citado, faremos uso de algumas classes e de seus métodos contidos na biblioteca ADO.NET. Usaremos DataSet, DataTable, DataColumn, DataView, e alguns recursos da System.IO, para acessar os arquivos em disco, vejo um breve descritivo deles na Tabela 01:

System.Data

Constitui a arquitetura ADO.NET, biblioteca com inúmeras classes, que tem como função primária, controlar o fluxo de dados das aplicações. A ADO.NET possibilita manipular de maneira eficiente múltiplas fontes de dados.

DataSet

É projetada explicitamente para tratar o acesso a toda a fonte de dados de forma independente. Podem ser usadas múltiplas e diferentes fontes de dados, intercaladas com dados de XML, ou usadas para controlar dados locais da aplicação. O DataSet contém uma coleção de uma ou mais DataTable, com as suas colunas e linhas de dados, assim como chaves primárias e estrangeiras e possibilita relacionamento entre esses objetos.

DataTable

Os objetos DataTable são usados para representar tabelas em um DataSet. Um DataTable representa uma tabela em memória com dados relacionados e pode ser usado de forma independente de uma DataSet.

DataColumn

O DataColumn é um bloco fundamental para construir o schema de um DataTable. Você constrói o schema adicionando uma ou mais DataColumn ao DataColumnCollection.

DataView

Um DataView permite criar diferentes visões dos dados armazenados em um DataTable. Usando um DataView, você pode exibir os dados de uma tabela organizando os dados de diferentes formas (Sort), e os mesmo podem ser filtrados, por estado ou expressão.

Tabela 01: Descritivo namespace e classes

Começando

Após abrirmos o Visual Studio.Net 205, criamos um novo projeto WindowsApplication, e adicionaremos os componentes citados na Tabela 02 no formulário:

Form

Name: Form1

Text: Disconnected Data

MenuStrip

Name: menuStrip1

Itens:

Name: fileToolStripMenuItem

Text: &File

Name: saveToolStripMenuItem

Text: &Save

Name: deleteRecordToolStripMenuItem

Text: &Delete record

Name: clearTableToolStripMenuItem

Text: &Clear table

Name: refreshToolStripMenuItem

Text: &Refresh

Name: toolStripSeparator1

Name: exitToolStripMenuItem

Text: &Exit

Name: aboutToolStripMenuItem

Text: &About

GroupBox

Name: groupBox1

Text: Data Set

DataGridView

Name: dataGridView1

GroupBox

Name: groupBox2

Text: Control

Button

Name: Button1

Text: &Save

Button

Name: Button2

Text: &Delete

Button

Name: button3

Text: &Refresh

Tabela 02: Listagem de componentes

Criando tabela e sua estrutura

Criaremos um método chamado InitializeDataSet(), e dentro dele iremos criar uma tabela com a classe DataTable montando sua estrutura base e suas colunas com a classe DataColumn, e atribuiremos ele a um DataSet, que por sua vez irá criar o Schema e o arquivo fonte xml, estas três classes fazem parte da namespace System.Data, procedimento abaixo:

DataSet ds;

DataTable dt = new DataTable("tbContacts");

DataColumn dc = new DataColumn("id", System.Type.GetType("System.Int32"));

dc.Unique = true;

dc.AutoIncrement = true;

dt.Columns.Add(dc);

dc = new DataColumn("fisrtname", System.Type.GetType("System.String"));

dt.Columns.Add(dc);

dc = new DataColumn("lastname", System.Type.GetType("System.String"));

dt.Columns.Add(dc);

dc = new DataColumn("phone", System.Type.GetType("System.String"));

dt.Columns.Add(dc);

dc = new DataColumn("email", System.Type.GetType("System.String"));

dt.Columns.Add(dc);

if (dt.DataSet == null)

{

ds = new DataSet("dsContactList");

ds.Tables.Add(dt);

ds.WriteXmlSchema(sPathSchema);

ds.WriteXml(sPathData);

}

Buscando dados

Para buscarmos os dados iremos criar um método do tipo DataView, e chamaremos ele de GetData(), que retornará um DataView, que posteriormente poderá ser utilizado em qualquer lugar, e mais especifico em nosso caso como DataSource do componente DataGridView. Vejam que é feita uma verificação se o Schema do xml existe, caso não ele irá inicializar o método e recriar a estrutura dos dados. Caso exista, ele irá diretamente buscar os arquivos e os carregará em um DataSet e logo após passa da tabela[0] para o DataView.

DataView dv = null;

try

{

if (!System.IO.File.Exists(sPathSchema))

this.InitializeDataSet();

DataSet ds = new DataSet("dsContactList");

ds.ReadXmlSchema(sPathSchema);

ds.ReadXml(sPathData);

dv = ds.Tables[0].DefaultView;

}

catch (Exception ex)...

Salvando alterações

Para podermos editar e excluir as células do DataGridView, devemos atribuir o valor "true" em suas propriedades AllowEdit e AllowDelete. E para salvar os dados contidos nesse DataGridVeiw em nosso documento xml, faremos um procedimento, criando o método SaveData(), que buscará os dados direto do DataSource deste componente e gravaremos eles usando o método WriteXml da classe DataView, logo após chamaremos o método RefreshGridView(), que simplesmente atualiza o DataGridView.

DataView dv = (DataView)dataGridView1.DataSource;

dv.AllowEdit = true;

dv.AllowDelete = true;

dv.Table.DataSet.WriteXml(sPathData);

this.RefreshGridView();

Apagando todos os dados

Simplesmente criamos um método chamado ClearData(), para facilitar a chamada e a manutenção do código e nele iremos chamar o método InitializeDataSet(), que recria nossa estrutura de dados.

this.InitializeDataSet();

this.RefreshGridView();

Atualizando DataGridView

Simplesmente criaremos um método chamado RefreshGridView(), e renovamos o DataSource, passando o valor null para limpar ele e repassando o dados buscados pelo GetData().

dataGridView1.DataSource = null;

dataGridView1.DataSource = GetData();

Apagando registro

Criaremos o método DeleteRecord(), que conterá o DataView, o qual repassará o valor da Table[0] do DataSet para ele, e apagamos a linha selecionada no DataGridView, descobrimos qual linha está selecionada buscando ela através da propriedade DataGridView.CurrentRow.Index, uma vez excluído os valores da memória, salvamos o documento xml, e atualizamos o DataGridView novamente.

DataView dv = null;

DataSet ds = new DataSet("dsContactList");

ds.ReadXmlSchema(sPathSchema);

ds.ReadXml(sPathData);

dv = ds.Tables[0].DefaultView;

dv.Table.Rows[dataGridView1.CurrentRow.Index].Delete();

dv.RowStateFilter = DataViewRowState.Deleted;

ds.WriteXml(sPathData, XmlWriteMode.WriteSchema);

this.RefreshGridView();

Conclusão

Neste artigo vimos como criar de forma simples um modelo de armazenamento de dados dentro de um documento XML usando a tecnologia ADO.NET. Vale lembrar que a biblioteca tem uma infinidade de classes e seus métodos, usamos uma mínima parte do que ela pode oferecer. Explore o assembly no object browser, e façam seus testes, as referências abaixo ajudam na compreensão do artigo.

Mais uma vez, fico a disposição para esclarecer dúvidas, inclusive se quiserem contribuir com melhorias e dicas para o artigo, bastam me enviar um e-mail.

Um abraço e até a próxima!

Referências

ADO.NET for the ADO Programmer

http://msdn.microsoft.com/library/en-us/dndotnet/html/adonetprogmsdn.asp?frame=true#adonetprogmsdn_topic5c

System.Data Namespace

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdata.asp

Introduction to Datasets

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbconDataSets.asp

Rodrigo S. Donini

Rodrigo S. Donini - Coordenador de desenvolvimento, líder de desenvolvimento nas tecnologias Microsoft, com fortes conhecimentos de client/server/web e metodologias de desenvolvimento.