ADO.NET - Trabalhando com Múltiplas tabelas relacionados
Eu já escrevi diversos artigos sobre o acesso a dados com VB.NET usando ADO.NET. Por isso poderei as vezes até ser repetitivo , tenham portanto paciência comigo. |
Abaixo uma pequena relação dos artigos que eu aconselho que você leia para saber conceitos básicos sobre o acesso a dados na plataforma .NET.
Vamos agora ao assunto deste artigo. Vou mostrar como podemos trabalhar com múltiplas tabelas relacionadas usando ADO .NET.
Eu tenho comigo que um bom desenvolvedor deve possuir bons conhecimentos sobre banco de dados e modelagem de dados. Eu não pretendo me aprofundar neste assunto mas creio que é meu dever relembrar velhos conceitos que para muitos poderão ser maçantes mas que para outros que estão começando pode fazer a diferença entre entender tudo ou não entender nada.
Um banco de dados - database - é um repositório (não supositório ) especial usado para armazenar e recuperar informações.
Um banco de dados relacional é um tipo específico de banco de dados onde os dados estão separados em tabelas , e , as tabelas estão relacionadas umas as outras através de valores que chamamos chaves. Abaixo eu estou mostrando o relacionamento entre as tabelas do banco de dados Biblio.mdb. Este banco de dados é um banco Access e vem junto com o Office e com o VB.
Relacionamento do banco de
dados Biblio.mdb : Um Editor(Publishers) possui muitos títulos (Titles) Um autor(Authors) pode possuir muitos títulos também. |
|
Figura 1.0 - Relacionamento das tabelas no banco de dados Biblio.mdb |
Nota: O Access é um tipo de banco de dados de pequeno porte para soluções caseiras e para pequenas empresas . Ele é constituído de várias tabelas em um único arquivo mdb.Um arquivo Access tem a extensão .mdb.
Através do VB .NET podemos armazenar e recuperar informações em muitos tipos de banco de dados , dentre os quais eu cito :
Oracle e DB2 - Usados para grandes empresas e sistemas com grande quantidade de informações
SQL Server - Para empresas médias e sistemas de médio porte
Access - Para pequenas empresas e soluções de pequeno porte.
Para fazer a conexão e o gerenciamento das informações com banco de dados o VB.NET utiliza ADO.NET.
ADO.NET armazena e transfere dados usando a XML - Extensible Markup Language ; através de dois tipos básicos de conexões :
SQLClient - Usado para conexão com o SQL Server
OLEDB - Usado para se conectar com todos os demais formatos de banco de dados.
Nota: Temos agora outros provedores como : ODBC .NET , MySQL .NET , Oracle .NET
Neste artigo eu vou usar o Access como exemplo por questão de simplicidade e por que nem todos possuem o SQL Server. Vou usar a versão Access 2000. A versão 2000 e 2002 usam a versão 4.0 do Jet DataBase Engine.(O motor do banco de dados)
Um banco de dados armazena dados sobre entidades individuais em tabelas separadas. Como exemplo de entidades presentes no banco de dados Biblio.mdb posso citar :Autores (Authors) , editores (Publishers) e títulos (Title).
Cada tabela é constituída de linhas e colunas:
- Linha (row) : representa uma informação sobre um Autor ou titulo ou editor. Também chamada de registro (record)
- Coluna (Column) - representa um campo de dados armazenados para cada autor, titulo ou editor. Ex: PubId , Title e ISBN.
Cada linha na tabela é identificada de forma única pelo campo chave primária. No caso acima as chaves para cada tabela estão representadas na figura 1.0 em negrito e são : PubId , ISBN , ISBN+Au_Id e Au_Id.
XML é um padrão da indústria usado para armazenar e transferir dados. Você não precisa saber como escrever XML para poder usar o VB e programar usando banco de dados. VB .NET gera automaticamente o XML que for necessário para sua aplicação.
Como XML armazena os dados na forma de texto identificados por tags como tags HTML podemos editar um arquivo XML com qualquer editor de textos . Isto facilita a transferência de dados na Web pois os dados não são barrados pelos firewalls.
Abaixo um exemplo de um arquivo XML. Vou representar neste código XML a tabela Authors. Esta tabela possui os seguintes linhas e colunas:(figura 2.0)
figura 2.0: A estrutura da tabela Authors |
<?xml version="1.0" enconding = "UTF-8"?> <dataroot xmlns:0d = "urn:schemas-microsoft-com:officedata"> <Authors <AU_Id>1</AU_Id> <Author>Macoratti</Author> <Year Born>09081975</Year Born> </Authors> <Authors> <AU_Id>2</AU_Id> <Author>Jessica</Author> <Year Born>03071990</Year Born> </Authors> </dataroot>
|
Nota : para saber mais sobre XML consulte a seção : XML/UML
Com ADO.NET podemos acessar banco de dados usando formulários criados no ambiente; Windows(Winforms) ou Web(WebForms). Ela fornece controles que você pode incluir em um formulário e que é usado para conectar e gerenciar dados em um banco de dados. Geralmente vinculamos (bound) as colunas das tabelas a estes controles.
Dentre estes controles podemos citar : Label , TextBox , ComboBox , ListBox , DataGrid e DataList.
As etapas básicas que você precisa fazer para acessar e gerenciar uma base de dados usando ADO.NET são :
Configurar uma conexão - a conexão acessa o banco de dados
Configurar um data adapter - Um Data Adapter manipula os dados retornados e atualizados e cria um DataSet. Um DataSet armazena linhas(registros) que foram retornadas.
Incluir os controles no formulário e definir as propriedades dos controles que fazem a vinculação entre os controles e as colunas da tabela que esta no DataSet.
Preencher o Dataset
Cada uma dessas etapas eu já abordei em artigos anteriores , e , como o procedimento e praticamente o mesmo , só mudando o nome da tabela , data adapter , dataset eu não vou repetir neste artigo como fazer cada uma dessas etapas , vamos ir um pouco mais além e tratar das tabelas relacionadas em um DataSet.
Para trabalhar com tabelas relacionadas em um DataSet é necessário um conhecimento básico do namespace System.Data e como interagir com ele.
Os objetos a seguir são usados para facilitar o relacionamento em um DataSet:
DataSet - representa na memória os dados que contém múltiplos objetos DataTable que podem ser relacionados com objetos DataRelation.
DataTable - Representa uma tabela de dados. O esquema de uma tabela de dados é definido por DataColumnCollection que cria a tabela. Quando duas tabelas estão relacionadas o objeto DataRelation usa DataColumns de cada tabela para relacionar os dados.
DataRelation - Quando acessamos registros relacionados um objeto DataRelation é passado via método GetChildRows ou GetParentRow. É o objeto DataRelation que determina que tabela relacionada consultar a fim de retornar os dados associados com a chamada dos métodos GetChildRows ou GetParentRow.
DataRow - Representa um registro individual. Os métodos GetChildRows ou GetParentRow são membros do objeto DataRow.
DataColumn - representa uma campo individual. Quando duas tabelas de dados estão relacionadas o objeto DataRelation usa as colunas de cada tabela para fazer o relacionamento.
Agora vamos criar uma aplicação no VB.NET . Nossa aplicação irá possuir uma conexão com uma base de dados access , um data adapter , um dataset que irá conter as tabelas relacionadas e alguns controles para exibir os dados.
1- Para criar uma nova aplicação do Tipo WIndows no VB .NET iremos fazer o seguinte :
No menu file escolha New Project
Na guia Project Types selecione Visual Basic Projects
Na guia Templates selecione Windows Application , dê um nome sugestivo a aplicação , TabelasRelacionadas e clique em OK.
O projeto TabelasRelacionadas será incluido no Solution Explorer
2- Vamos agora criar uma conexão com o banco de dados Northwind.mdb (formato Access) para isto eu vou usar o Server Explorer.
Para abrir o Server Explorer selecione o menu View e a seguir Server Explorer ou Ctrl+Alt+S
Na janela Server Explorer clique com o botão direito do mouse em Data Connections e selecione Add Connection
Na aba Provedor Selecione o Microsoft Jet 4.0 Ole Db Provider
Na aba Conexão clique no botão com reticências e selecione o banco de dados Northwind.mdb
A seguir expanda a conexão criada e clique em Tables de forma a visualizar as tabelas disponíveis
|
|
Para criar objetos data adapter e connections basta arrastar e soltar a tabela Clientes no formulário padrão form1.vb. Serão criados um objeto connection - OleDbConnection1 e OleDbDataAdapter1
Vamos definir o nome da conexão para - dcNorthwind e do data adapter para daClientes
Vamos agora arrastar a tabela Pedidos para o formulário. Um segundo data adaptaer - OleDbDataAdapter2 - vamos alterar seu nome para daPedidos.
Para gerar o DataSet que irá conter as tabelas relacionadas no menu Data selecione - Genereate DataSet.
Na janela Generate DataSet marque as opções :
New
Marque as duas tabelas - Clientes e Pedidos.
Marque a opção: Add this DataSet to the designer.
Clique no botão OK
Um arquivo chamado dsNortwind.xsd é incluído no Solution Explorer e uma instância do DataSet surge barra de componentes.
Vamos criar o relacionamento entre as tabelas Clientes e Pedidos. No banco de dados temos que o relacionamento é o seguinte :
- Temos aqui
o tipo de relacionamento do tipo UM-Para-Muitos - Um cliente pode ter muitos pedidos - O relacionamento entre as tabelas e feita pela chave CódigoDoCliente das duas tabelas.
|
Para criar este relacionamento entre as tabelas faça o seguinte :
Clique duas vezes no arquivo dsNorthwind.xsd. O mesmo será aberto no Descritor XML
Abra a ToolBox e você verá a guia XML
Arraste a o esquema Relation para a tabela Pedidos
Na janela Edit Relation , defina as propriedades conforme a figura abaixo:
Após confirmar a operação se você clicar no arquivo dsNorthwind.xsd irá visualizar o seguinte:
Esta tudo pronto para visualizarmos os dados no formulário ; para isto vou trabalhar com os controles ComboBox , ListBox e Rich text box , então vamos lá...
No Solution Explorer clique com o botão direito do mouse sobre o arquivo form1.vb e selecione View Desginer
Insira um controle ListBox no formulário e chame-o de lstPedidos
Inclua também um controle RichTextBox e mude seu nome para rtbDetalhes
Insira agora um controle Combobox com o nome de cbClientes
Inclua também uma etiqueta(Label) chamada lblinfo para que possamos exibir informações sobre a quantidade do pedido
Salve o projeto. (O layout do formulário esta exibido abaixo)
Vamos por o projeto para funcionar :
1- Vamos carregar a combobox de forma a exibir o nome da empresa para isto selecione a combobox e defina as seguintes propriedades:
(Veja figura ao lado) |
Agora vamos preencher as tabelas com dados para isto vamos ter que incluir código no evento Load do formulário:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'desabilita as constraints no dataset DsNorthwind1.EnforceConstraints = False 'preenche as tabelas com dados daPedidos.Fill(DsNorthwind1) daClientes.Fill(DsNorthwind1) 'habilita as constraints novamente DsNorthwind1.EnforceConstraints = True End Sub |
Salve o projeto e rode a aplicação pressionando F5. Você verá a combo carregada com os nomes das empresas:
Vamos implementar a navegação entre os registros relacionados das tabelas. Para acessar dados entre tabelas relacionadas em uma relação UM-Para-Muitos você deve selecionar uma linha(registro) e a seguir retornar os registros relacionados invocando o método GetChildRows ou o método GeParentRow passando-os no apropriados DataRelation. (GetChildRows retorna os dados em array de objetos DataRow e GetParentRow retorna uma única linha)
Para mostrar isto vamos incluir código para retornar todos os pedidos (Child rows) para o cliente selecionado na combobox ; o código será incluindo no evento SelectedIndexChanged da combobox. Quando houver alteração de cliente na combobox o evento ComboBox.SelectedIndexChanged irá ser disparado e iremos preencher o listbox com os pedidos para cada cliente selecionado.
Podemos chamar o método GetChildRows baseado no cliente selecionado de forma a atribuir todos os pedidos relacionados a um array de data rows chamado draPedidos. Para implementar isto faça o seguinte:
No Solution Explorer clique com o botão direito do mouse no form1 e selecione View Designer
Clique duas vezes sobre a combobox de forma a criar o evento SelectedIndexChanged
Inclui o código abaixo no evento:
Private Sub cboClientes_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles cboClientes.SelectedIndexChanged 'declara uma string para manipular os clientes selecionados Dim codigoClienteSelecionado As String codigoClienteSelecionado = cboClientes.SelectedValue.ToString() 'declara um data row para manipular os registros do clientes selecionado Dim drClienteSelecionado As DataRow drClienteSelecionado = DsNorthwind1.Clientes.FindByCódigoDoCliente(codigoClienteSelecionado) 'declare um array de data rows para manipular os registros relacionados Dim draPedidos() As DataRow 'em getChildRows - ClentesPedidos - é o nome dado a relação criada draPedidos = drClienteSelecionado.GetChildRows("ClientesPedidos") 'exibe a quantidade de pedidos na label lblinfo.Text = draPedidos.Length & " Pedidos para " & codigoClienteSelecionado End Sub
|
Salve a aplicação e rode o projeto. Você irá ver a quantidade de pedidos relacionados a cada cliente sendo exibidos na label no formulário.
Como já temos os registros de um cliente selecionado armazenado em um array de data rows vamos exibí-los no formulário. A aplicação deverá interagir através do array com os dados retornados através do método GetChildRows e incluir o NúmeroDoPedido para cada registro relacionado como um item individual no listbox. O código para fazer este serviço deverá ser incluido no evento cboClientes_SelectedIndexChanged ; Abaixo o código completo com a inclusão destacada:
Private Sub cboClientes_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles cboClientes.SelectedIndexChanged 'declara uma string para manipular os clientes selecionados Dim codigoClienteSelecionado As String codigoClienteSelecionado = cboClientes.SelectedValue.ToString() 'declara um data row para manipular os registros do clientes selecionado Dim drClienteSelecionado As DataRow drClienteSelecionado = DsNorthwind1.Clientes.FindByCódigoDoCliente(codigoClienteSelecionado) 'declare um array de data rows para manipular os registros relacionados Dim draPedidos() As DataRow 'em getChildRows - ClentesPedidos - é o nome dado a relação criada draPedidos = drClienteSelecionado.GetChildRows("ClientesPedidos") 'exibe a quantidade de pedidos na label lblinfo.Text = draPedidos.Length & " Pedidos para " & codigoClienteSelecionado 'limpa o listbox e o richtextbox lstPedidos.Items.Clear()
rtbDetalhes.Text = "" 'exibe o numero de cada pedido do cliente selecionado Dim drPedidos As DataRow For Each drPedidos In draPedidos
lstPedidos.Items.Add(drPedidos("NúmeroDoPedido")) End Sub
|
Ao rodar o projeto e selecionar um cliente o número de cada pedido do cliente selecionado será exibido na listbox.
Para terminar precisamos exibir os detalhes do pedido selecionado no controle RichTextBox. Para fazer isto vamos ter que incluir mais duas tabelas ao DataSet existente e criar um novo objeto DataRelation.
Visualize o Server Explorer e arraste as tabelas - Detalhes do Pedido e Produtos para formulário.
Serão criados mais dois data adapters , altere seus nomes para : daDetalhesPedidos e daProdutos
No menu Data selecione Generate DataSet e defina as propriedades conforme figura abaixo:
Precisamos agora criar os relacionamentos entre as tabelas Produtos e Detalhes do Pedido recém incluídas.
No Solution Explorer clique duas vezes no arquivo dsNorthwind.xsd
No descritor XML visualize a toolbox e arraste um esquema DataRelation para o arquivo Detalhes do Pedidos. (Conforme abaixo)
Na janela - Edit Relation - configure as propriedades conforme figura abaixo:
Agora arraste um esquema DataRelation para o arquivo Detalhes do Pedidos. E na janela Edit Relation configure as propriedades conforme figura abaixo
Agora precisamos incluir o código para preencher as tabelas produtos e detalhes do pedido. No evento Load do formulário exibimos o código completo com o código incluído destacado:
Private
Sub Form1_Load(ByVal
sender As System.Object, ByVal e
As System.EventArgs) Handles
MyBase.Load
DsNorthwind1.EnforceConstraints = False 'preenche as tabelas com dados daPedidos.Fill(DsNorthwind1) daClientes.Fill(DsNorthwind1)
'habilita as constraints novamente DsNorthwind1.EnforceConstraints = True 'preenchendo as tableas produtos e detalhes do pedidos daDetalhesPedidos.Fill(DsNorthwind1) daProdutos.Fill(DsNorthwind1) End Sub |
Vamos finalmente exibir os detalhes dos pedidos no controle RichTextBox. O código para fazer isto invoca o método GetChildRows baseado no pedido selecionado na listbox. Todos os registros relacionados na tabela Detalhes dos Pedidos são atribuidos a um array de data rows que vou chamar de draDetalhesPedidos. O conteúdo de cada data row é exibido então no rich text box.
Clique duas vezes na listbox de modo a criar o evento SelectedIndexChanged e inclua o seguinte código:
Private Sub lstPedidos_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPedidos.SelectedIndexChanged
'limpa o controle richtextbox rtbDetalhes.Clear()
'declara um inteiro para tratar o Numero do pedido selecionado Dim codigoPedidoSelecionado As Integer'efetua uma conversão explicita (casting) do item selecionado para um integer codigoPedidoSelecionado = CType(lstPedidos.SelectedItem, Integer)
'declara um data row para tratar o pedido selecionado Dim drPedidoSelecionado As DataRowdrPedidoSelecionado = DsNorthwind1.Pedidos.FindByNúmeroDoPedido(codigoPedidoSelecionado)
'declara um array de data rows a fim de tratar os registros relacionados Dim draDetalhesPedido() As DataRowdraDetalhesPedido = drPedidoSelecionado.GetChildRows("ClientesDetalhesDoPedido")
Dim detalhes As String Dim drDetalhes As DataRowDim dcDetalhes As DataColumn
For Each drDetalhes In draDetalhesPedido For Each dcDetalhes In drDetalhes.Table.Columns detalhes &= dcDetalhes.ColumnNa me & " : " & drDetalhes(dcDetalhes).ToString() & ControlChars.CrLf Next NextrtbDetalhes.Text = detalhes End Sub |
Agora rode o projeto e você verá todas as funcionalidades implementadas funcionando.
Ao selecionar um cliente temos o pedidos referentes ao cliente selecionado
Clicando em um pedido temos os detalhes do pedido com os dados do produto incluído
Abaixo o formulário exibindo o resultado
Parabéns! você já sabe trabalhar com tabelas relacionadas no VB.NET e percebeu que não é tão complicado assim. Cabe a você expandir seus conhecimentos melhorando a interface usada no exemplo.
Em um próximo artigo irei falar de tabelas com relacionamentos muitos para muitos e em como tratar isto no VB.NET, até lá... .
Salmos 19:1 Os céus proclamam a glória de Deus e o firmamento anuncia a obra das suas mãos.
Salmos 19:2 Um dia faz declaração a outro dia, e uma noite revela conhecimento a outra noite.
Salmos 19:3 Não há fala, nem palavras; não se lhes ouve a voz.
Veja os Destaques e novidades do SUPER DVD VB (sempre atualizado) : clique e confira ! Quer migrar para o VB .NET ? Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira... Quer aprender C# ??
Chegou o
Super DVD C# com exclusivo material de
suporte e vídeo aulas com curso básico sobre C# |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: