Utilizando DataSet como Tabela Temporária
No desenvolvimento de aplicações, sempre nos deparamos com a necessidade de armazenar alguns valores para efeito de cálculo, verificações ou outras necessidades.
Para isto um DataSet pode ser bem útil. Como todos nós sabemos existe dois tipos de DataSet o tipado e não-tipado. O tipado seria uma representação da tabela do Banco de dados possuindo os mesmos tipos, relacionamentos. O não-tipado seria aquele que não representa fielmente uma tabela, ou seja, podemos defini-lo da maneira necessária para nossa utilização e será neste que iremos focar.
Para definirmos um DataSet podemos fazer isto no Designer do Visual Studio ou via código. Vamos utilizar a opção via código primeiro, pois também é a mais utilizada. Para isto será necessário a implementação de um projeto Windows Application.
Definiremos em nosso formulário uma variável global do tipo DataSet (Para utilizar este objeto é necessário que o namespace System.Data seja informado), conforme pode ser visto na Figura 1.
Figura 1 – Definindo a variável global dataset1
Após definido nossa variável global, iremos implementar a nossa tabela temporária, sendo que os campos pertencentes dependerão exclusivamente da funcionalidade a ser implementada. Para isto definiremos o método CarregaTabelaTemp como pode ser visto na Listagem 1.
Listagem 1 – Definindo estrutura da tabela temporária
private void CarregaTabelaTemp()
{
// Instancia a variável global
dataset1 = new DataSet();
// Definindo variável de tabela
DataTable dt = new DataTable("temp");
// Definindo os campos da Tabela
dt.Columns.Add("Codigo", typeof(int));
dt.Columns.Add("Descricao", typeof(string));
dt.Columns.Add("Data", typeof(DateTime));
dt.Columns.Add("Imagem", typeof(Bitmap));
// Incluindo a tabela no DataSet
dataset1.Tables.Add(dt);
}
Como pode ser visto no método CarregaTabelaTemp, este tem como finalidade definir a estrutura da tabela temporária que estará em nosso dataset1. Para adicionar as colunas em uma tabela é necessário informar o nome da coluna a ser adicionada e o tipo da mesma. Após todos os tipos definidos é só adicionar a tabela no DataSet.
Lembrando que o DataSet também é um conjunto de tabelas então, de acordo com a necessidade, pode ser adicionada uma ou várias tabelas em um mesmo DataSet.
Se caso necessário podemos inserir em nossa tabela algumas validações como chave primária, índex e até mesmo chave estrangeira, fazendo com que dados não se repetem ou obedeçam a uma determinada chave.
Para isto o novo código do método CarregaTabelaTemp ficaria como mostra a Listagem 2.
Listagem 2 – Definindo estrutura da tabela temporária com Chave Primária
private void CarregaTabelaTemp()
{
// Instancia a variável global
dataset1 = new DataSet();
// Definindo variável de tabela
DataTable dt = new DataTable("temp");
// Definindo os campos da Tabela
dt.Columns.Add("Codigo", typeof(int));
dt.Columns.Add("Descricao", typeof(string));
dt.Columns.Add("Data", typeof(DateTime));
dt.Columns.Add("Imagem", typeof(Bitmap));
// Definindo a coluna Código como Chave Primária
dt.PrimaryKey = new DataColumn[] { dt.Columns["Codigo"] };
// Definindo que valores da coluna descrição não podem se repetir
dt.Columns["Descricao"].Unique = true;
// Incluindo a tabela no DataSet
dataset1.Tables.Add(dt);
}
Como pôde ser viso na Listagem 2 foi definida para a tabela temporária qual coluna faz parte da chave primária, sendo que se tivesse mais alguma seria só incluir mais um item no array separando por vírgula. Ao tentar gravar um registro o próprio DataSet verifica se não há inconsistência se houver abortar a gravação.
Também foi definido que a coluna Descricao é uma coluna que não aceita valores repetidos, fazendo com que aborte a gravação caso encontre.
Assim como definimos estes objetos podemos definir também relacionamento entre tabelas e deixando com que o próprio DataSet verifique e valide ou aborte a gravação ou exclusão dos dados.
A partir deste ponto o dataset1 esta pronto para operações de inserção, exclusão, alteração e pesquisa de dados. Para podermos executar estas operações iremos desenvolver um cadastro simples, onde os campos na tela serão ligado nos campos da nossa tabela temporária.
Para isto o formulário de cadastro deverá ter o designer de acordo com a Figura 2.
Figura 2 - Desenvolvendo Formulário de teste
Depois de desenvolvido a Interface do formulário de cadastro será necessário realizar o Binding entre as colunas da tabela e os campos da tela. Para isto necessitaremos de um componente chamado BindingSource. Este terá como responsabilidade realizar o Binding dos controles e atualizar os valores no dataset1. Por ser um componente este não aparecerá na tela em tempo de execução somente em tempo de designer. Outro controle que utilizaremos é o BindingNavigator que ao ser setado um BindingSource conseguirá executar as funções de navegação, exclusão e inserção automaticamente no BindingSource, restando para nós desenvolvermos o código realizará a salvação dos registros.
Para realizar o Binding dos controles foi desenvolvido o método BindingCtrl como pode ser visualizado na Listagem 3.
Listagem 3 – Método que irá setar a propriedade DataBinding dos controles
private void BindingCtrl()
{
bindingSource1.DataSource = dataset1;
bindingSource1.DataMember = dataset1.Tables[0].TableName;
txtcodigo.DataBindings.Add(new Binding("TEXT",bindingSource1,"codigo",true));
txtcodigo.DataBindings[0].FormatString = "N1";
txtdescricao.DataBindings.Add(new Binding("TEXT", bindingSource1, "descricao"));
datetime.DataBindings.Add(new Binding("TEXT", bindingSource1, "data",true));
picturebox.DataBindings.Add(new Binding("IMAGE", bindingSource1, "imagem",true));
}
Após o desenvolvimento destes métodos poderemos realizar a inserção e exclusão dos dados na tabela temporária via designer para isto no evento Load do form realizaremos a seguinte chamada como pode ser vista na Listagem 4.
Listagem 4 – Chamadas dos métodos padrão para o formulário
private void Form1_Load(object sender, EventArgs e)
{
CarregaTabelaTemp();
BindingCtrl();
}
Para que o BindingNavigator consiga salvar os dados na tabela temporária, foi desenvolvido o evento no botão de salvar do mesmo que executa o código que pode ser visto na Listagem 5.
Listagem 5 – Código responsável por salvar os registros
private void saveToolStripButton_Click(object sender, EventArgs e)
{
this.Validate();
bindingSource1.EndEdit();
}
Com todos estes métodos criados agora conseguiremos salvar dados na tabela temporária, clicando no botão de adicionar e depois dos dados preenchidos o botão de salvar. A exclusão dos registros fica por conta do BindingSource, o mesmo já se encarrega de remover da própria lista e da tabela que está ligado a ele o registro que está sendo excluído.
Na Figura 3 podemos visualizar os registros que foram adicionados na tabela temporária.
Figura 3 - Dados inseridos na Tabela Temporária
Nem sempre os dados a serem incluídos em uma tabela temporária deverão ser digitados em um cadastro mas sim via código. Esta segunda parte deste artigo mostrará como incluir e excluir linhas via código.
Como vimos anteriormente o grande responsável pela inserção e exclusão dos dados quando utilizamos uma interface é o BindingSource, pois ele possui todos os métodos e eventos que conseguem recuperar o valor que está no controle e inseri-los ou excluí-los na tabela temporária.
Quando estamos trabalhando via código não há necessidade para utilizarmos este componente, significando que o tratamento para exclusão e inserção dos dados será tratada por nós, mas não se preocupem o processo é tão simples como o outro.
Bom como já foi dito o DataSet pode ter um conjunto de DataTable que por sua vez tem um conjunto de DataColumns e DataRows ou seja, para adicionarmos mais registros em uma tabela deveremos criar uma nova Row e em cada Column informar o valor que deverá ser gravado. Como pode ser visto na Listagem 6 o código para inserção de dados é bem tranqüilo.
Listagem 6 – Inserindo registros via código
private void button1_Click(object sender, EventArgs e)
{
DataRow row = dataset1.Tables[0].NewRow();
row["Codigo"] = 3;
row["Descricao"] = "Teste Via Código";
row["Data"] = DateTime.Now;
row["Imagem"] = new Bitmap(@"C:\Documents and Settings\All Users\Documentos\Minhas imagens\Amostras de imagens\Ninféias.jpg");
dataset1.Tables[0].Rows.Add(row);
}
Resumindo o código apresentado, o mesmo criará uma nova linha através do método NewRow() da primeira tabela do DataSet. Após para esta linha que está sendo inserida em cada coluna existente na tabela temporária está sendo setado um valor de acordo com o tipo da coluna que foi criado conforme Listagem 1. Após setado todos os valores de todas as colunas necessárias, a linha finalmente é inserida na tabela.
Para a exclusão de dados podemos realizar de várias maneiras, as duas mais utilizadas são:
· Quando se conhece qual é a linha a ser escluída;
· Quando é necessário recuperar a linha através de uma pesquisa para depois excluí-la;
Para a primeira opção o código de exclusão ficaria ligeiramente simples como pode ser visto na Listagem 7.
Listagem 7 – Excluindo registro via código
private void button2_Click(object sender, EventArgs e)
{
dataset1.Tables[0].Rows.RemoveAt(0);
}
Para a segunda opção teremos que recuperar primeiramente um DataRow através de uma consulta a ser realizada na tabela temporária para depois sim excluí-lo.
Para realizar uma pesquisa em uma tabela temporária utilizaremos o método Select(). Este método sempre retornará uma conjunto de DataRow e pode receber como parâmetro somente o filtro a ser aplicado ou, o filtro a ordem a serem consultados os dados e o estado da linha(Alterados, Excluídos, Adicionados) como critério de filtro. Em nosso exemplo vamos utilizar somente o primeiro overload como pode ser visualizado na Listagem 8.
Listagem 8 – Excluindo registro via código
private void button2_Click(object sender, EventArgs e)
{
DataRow[] row = dataset1.Tables[0].Select("codigo = 3");
if (row.Length > 0)
dataset1.Tables[0].Rows.Remove(row[0]);
}
No código da Listagem 8 vimos também como se realiza pesquisa em uma tabela temporária utilizando o método Select() que sempre irá retorna como Array o resultado.
Conclusão
Bom neste artigo vimos como definir a estrutura de nossa tabela temporária, definindo o nome e tipo de colunas.Vimos também o quanto fácil é de se trabalhar com a tabela temporária tanto inserindo e excluindo dados vida Designer ou via código. Conhecemos e utilizamos o método de Select() do objeto DataTable, permitindo recuperar os dados de acordo com o filtro informado, possibilitando ordenar os dados e filtrar também pelo estado das linhas na tabela.
Espero que este artigo seja de grande valia nos possibilitando agora utilizar tabela temporária no Visual Studio 2005, facilitando recuperação de dados, inserção e exclusão de dados.