sábado, 21 de janeiro de 2012

Windows Forms - Mestre-Detalhe utilizando o Ado Entity Framework

Neste artigo irei abordar como poderemos montar um relacionamento 1 para muitos, mais conhecido como Mestre-Detalhe utilizando a tecnologia Ado Entity Framework junto com o Visual Studio 2010 e o SQL Server 2008. Iremos aprender alguns comandos básicos para se trabalhar com esta arquitetura. A Base de Dados utilizada será a NorthWind, para quem não sabe, ela é padrão no banco de Dados SQL Server. Para o pessoal que não possui a mesma, segue o link abaixo para o download e instalação:
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=23654

Uma breve Introdução ao Ado Entity Framework

O Ado Entity Framework oferece um mapeamento objeto relacional (O/R) de forma a permitir o mapeamento das tabelas do Banco de Dados como objetos para abstrair o acesso a dados. Deixa para o desenvolvedor, que já conhece o ramo de orientação a objetos, ótimos mecanismos de acessar banco de dados sem precisar conhecimento aprofundado de banco de dados e de T-SQL (Transact SQL).

O melhor disto é que o desenvolvedor poderá fazer mapeamento para diversas bases de dados, como: SQLServer, Oracle, DB2, MySql, PostgreSQL, SQLite, VistaDB, Informix, Sybase e assim como para outras fontes tais como: XML e serviços.


Montando o exemplo


Trabalharemos com as tabelas “Customers” e “Orders”, que significa respectivamente Cliente e Pedidos do Cliente. Para isto abra o Visual Studio 2010 e inicie um novo Projeto Windows Forms. No formulário criado iremos definir algumas propriedades, veja adiante:

Font: Tahoma; 9pt
FormBorderStyle: FixedDialog
Text: The Club – Relacionamento Mestre-Detalhe
Name: FrmPedidoCliente
Size: 900;600
StartPosition: CenterScreen
MaximizeBox: False
MinimizeBox: False


Depois de definirmos estas propriedades, adicionaremos em nossa solução um Modelo de Dados para podermos trabalhar com as duas tabelas anteriormente citadas.  O Entity Data Model é um arquivo XML com as informações do banco de dados e das classes que será a visão. Para isto clique com o botão direito em nossa Class Library “WindowsFormsApplication” em seguida em Add/New Item.


Figura 01: Modelo de Dados.
Escolha “ADO.NET Entity Data Model”, em Name defina como Model.edmx e em seguida clique em Add.
Na próxima tela escolha “Generate From Database”, isto indica que iremos criar nossos objetos a partir do Banco de Dados.
A tela seguinte é muito importante, pois  é onde criamos a conexão com o SQL Server, no nosso caso específico clicaremos no botão “New Conection” e em “Connection Properties” definiremos as seguintes configurações:

Data source: Microsoft SQL Server (SqlClient)
Server name: THIAGO-NOTE
Log on to the server: Use SQL Server Authentication
User name: sa
Password: <senha>
Select or enter a database name: NorthWind


Na Figura 02 configuramos os dados para se conectar com uma Base de Dados SQL Server 2008, no caso se os senhores estivessem utilizando outra Base as configurações seriam outras.
É interessante “Testar” a conexão no Botão “Test Conection”, pois se ocorrer algum erro de configuração poderemos arrumar e evitar problemas futuros.


Figura 02: Propriedades da Conexão.
O próximo passo é interessante, é nele onde iremos escolher nossas tabelas Customers e Orders e o restante das configurações deixaremos como padrão.


Figura 03: Entity Data Model Wizard.
A Figura 04 nos mostra as duas tabelas utilizadas e o relacinamento 1 para muitos. Notem que pelo fato destas duas tabelas já estarem relacionadas no SQL Server, não precisaremos configurar praticamente nada no Modelo de Dados. Tudo é realizado automaticamente.


Figura 04: Relacionamento Mestre-Detalhe.
Para obter mais detalhes do relacionameto, dê um duplo clique e verifique as seguintes configurações:

Principal:
Customers
Dependent: Orders
Principal Key: CustomerID
Dependent Property: CustomerID


Temos nossa tabela Customers como “Mestre” e o campo CustomerID como Chave Primária e a tabela Orders como Detalhe e o campo CustomerID como chave estrangeira. Neste momento nosso relacionamento está completo.
Deveremos adicionar nosso DataSource para trabalharmos com as duas tabelas, para isto clique no item “Data Sources” e em seguida no item “Add New Data Source”. Na próxima tela adicione um “Object” e em seguida clique em “Next”.
É importante ressaltar que no caso do Entity Framework trabalhamos com Objetos, estaremos lidando diretamente com Objetos de Dados, pelo fato desta arquitetura ser fortemente trabalhada com Classes de Objetos.
Na Figura 05 é disponibilizado os Objetos de dados utilizados no Sistema, selecione “Customers”, mais para frente veremos que a classe “Customers” estará diretamente relacionada com a Classe “Orders”. Assim finalizamos nosso processo clicando no botão “Finish”.


Figura 05: Selecionando a Classe Customer.
Vejam que criamos o Datasource para ser utilizado em nosso projeto. Para localizarmos o mesmo clique no item de menu “Data” e escolha “Show Datasources”, aparecerá na região esquerda do Visual Studio a tabela “Customers” e junto com a mesma a “Orders”.
A figura 06 ilustra como está ficando nosso exemplo.


Figura 06: Data Source.
Veremos a facilidade para montar um relacionamento Mestre-Detalhe. Para isto arraste o Objeto ”Customers” para o Formulário e vejam que automaticamente foi criado dois componentes: “customersBindingSource” e “customersBindingNavigator” sendo o primeiro reponsável por trabalhar com os dados da tabela “Customers” e o segundo uma barra para navegar nos registros das tabelas relacionadas.
Por final arraste o objeto “Orders” para o formulário e automaticamente foi criado o componente “ordersBindingSource”, responsável por trabalhar com os dados da tabela “Orders”.
Abaixo as configurações dos componentes:

customersDataGridView

 AlternatingRowsDefaultCellStyle:
DataGridViewCellStyle { BackColor=Color [A=255, R=255, G=255, B=192] }
DataSource: customersBindingSource
Size: 882;274


ordersDataGridView

AlternatingRowsDefaultCellStyle:
DataGridViewCellStyle { BackColor=Color [A=255, R=255, G=255, B=192] }
DataSource: OrdersBindingSource
Size: 882;231


A Figura 07 ilustra como está ficando nosso exemplo.


Figura 07: Formulário Mestre-Detalhe.
Para darmos continuidade em nosso cadastro, deveremos codificar uma pequena parte do mesmo. É interessante notar que o Ado Entity Framework junto com o conjunto de componentes do Visual Studio nos proporciona uma facilidade tremenda no desenvolvimento de Cadastros, veremos que com uma quantia pequena de código estaremos trabalhando com os dados das tabelas relacionadas.
Para isto trabalharemos com o evento Load do formulário. É ali onde carregaremos todos os dados das tabelas.

Por se tratar de apenas um exemplo simples isto é válido, mas ressalto que não é uma prática recomendada para se trabalhar no desenvolvimento de sistemas, é recomendável sempre ter uma consulta parametrizada para não ter uma sobrecarga de dados deixando o sistema lento. Mas isto deixemos para um próximo artigo.

Voltando ao assunto,  antes de trabalhar com o evento Load, instanciaremos o Contexto de Dados, veja o código abaixo:

NorthwindEntities Db = new NorthwindEntities();

E no Evento Load:

private void FrmPedidoCliente_Load(object sender, EventArgs e)
{
  customersBindingSource.DataSource = Db.Customers;
}

Para Salvar os dados no Banco de Dados, deveremos trabalhar com o evento “SaveChanges”, mas primeiramente na região superior do bindingNavigator, habilitaremos o Botão Salvar. Clique com o Botão direito e escolha “Enable” e em seguida dê um duplo clique. Automaticamente será criado um evento “customersBindingNavigatorSaveItem_Click”.

Neste evento colocaremos o código abaixo:
private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
      Validate();
      customersBindingSource.EndEdit();
      ordersBindingSource.EndEdit();
      try
         {
               Db.SaveChanges();
               MessageBox.Show("Registro Salvo Com Sucesso!");

         }
      catch (Exception Ex)
         {
               MessageBox.Show("Ocorreu uma excessão ao salvar estes     dados! "+ Ex.Message);

         }
}

O evento Validade() serve para validar os dados a serem salvos. O Evento EndEdit() serve para atualizar os dados.
O try... Catch... nos informa se ocorreu ou não alguma excessão na hora de gravar os dados no Banco de Dados. É importante utilizá-lo pois podemos tratar o erro ocorrido mostrando na tela para o usuário.

Implementando uma consulta de dados


Neste mesmo formulário, iremos implementar uma consulta por Países utilizando uma combobox para carregar os dados e em seguida filtrá-los para serem mostrados nos DatagridViews.
Na região superior localize o componente “customersBindingNavigator” e com o botão direito adicione uma “Combobox” e em seguida implemente o evento “SelectedIndexChanged”

private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    var Paises = from customer in Db.Customers
where customer.Country ==          toolStripComboBox1.SelectedItem
            select customer;

            customersBindingSource.DataSource = Paises;
}

No evento Load do formulário modifique-o para o seguinte código:

private void FrmPedidoCliente_Load(object sender, EventArgs e)
{
            var Paises = from customer in Db.Customers
                         where customer.Country != ""
                         orderby customer.Country
                         select customer.Country;


            foreach (var item in Paises.Distinct())
            {
                toolStripComboBox1.Items.Add(item);
            }
                   
}

O evento Load será responsável por carregar os dados na Combobox, foi utilizado uma consulta utilizando o LINQ e logo em seguida pegamos o objeto “Paises” e adicionamos  uma Combobox. O Método Distinct() é o mesmo utilizado em consultas T-SQL, ou seja, estaremos mostrando apenas um item por país.

Já o evento “SelectedIndexChanged” filtrará os clientes dos países da tabela “Customers” usando a propriedade “Selecteditem” junto com a cláusula “Where”.

Figura 08: Exemplo Completo.
Conclusão

Vimos neste artigo como montar um Cadastro junto com uma consulta utilizando pouca codificação. Aprendemos um pouco de LINQ TO ENTITY junto com alguns comandos básicos para se trabalhar com Banco de Dados. Montamos um exemplo simples porém com todas as funções básicas de um cadastro, tais como: Inclusão, Alteração, Exclusão e Pesquisa.
Fico por aqui, um forte abraço e até o mês que vem!

Nenhum comentário:

Postar um comentário