Entity
Framework - Conceitos Básicos - Exibindo Mestre-Detalhe
Neste artigo eu procuro dar uma visão geral sobre a utilização do Entity Framework para realização de tarefas básicas de manutenção de dados com alguns padrões usados em banco de dados. Para isso eu irei montar alguns cenários mostrando como usar o EF para realizar a tarefa de exibição e manutenção dos dados quando for o caso. Abaixo segue um resumo dos cenários que serão abordados:
Em todos os cenários irei usar uma aplicação Windows forms criada no Visual Studio 2008 SP1 e o banco de dados SQL Server 2008 Express.
Vou iniciar definindo o modelo básico usado na aplicação exemplo. Eu vou usar um banco de dados bem parecido com o Northwind.mdf mas com uma estrutura mais enxuta para facilitar o trabalho. Ele foi criado usando o SQL Server Management Studio 2008. Segue a baixo a estrutura do banco de dados que eu chamei Macoratti.mdf:
Nota: Veja o artigo : Usando o SQL Server Management Studio
![]() |
Pegue o script
para gerar o modelo acima aqui:
MacorattiSQL.zip
Abra então o Visual Studio 2008 SP1 e crie um novo projeto do tipo Windows Forms chamado EF_Crud3;
A seguir vamos gerar um Entity Data Mode (EDM)l a partir do modelo exibido na figura acima;
No menu Project -> New Item , selecione em Templates o item ADO .NET Entity Data Model e informe o nome Macoratti.edmx e clique em Add;
![]() |
Dessa forma teremos o nosso modelo conceitual gerado conforme a figura a seguir:
![]() |
Este será o nosso ponto de partida para as considerações e para os cenários que iremos desenhar para mostrar como usar o EF em algumas situações de manutenção de dados.
Cenário 3 - Exibindo Mestre - Detalhes
Neste cenário o que pretendemos e exibir as informações sobre categorias e produtos em um relacionamento do tipo Mestre-Detalhes onde em um DataGridView(gdvCategorias) serão exibidos as categorias e em outro DataGridView (gdvProdutos) serão os produtos relacionados, de forma que ao selecionar uma categoria os produtos relacionados seja automaticamente exibido.
Adicione um novo formulário frmMestreDetalhes.vb no projeto e inclua neste formulário os seguintes controles : 1 Button e 2 DataGridView conforme o leiaute abaixo:
![]() |
Ao executar o projeto e selecionar uma categoria você quer exibir os seus produtos da seguinte forma:
![]() |
Vejamos como obter este resultado usando o Entity Framework.
1- Exibindo as categorias no primeiro DataGridView
A primeira coisa que vamos fazer é definir uma consulta que deve obter os objetos Categoria e Produto a partir das entidades definidas no EDM.
Vamos declarar o seguinte namespace no projeto:
Imports System.Data.Objects
O
namespace System.Data.Objects é usado para criar e gerenciar objetos
de entidades e o EF usa o
ObjectQuery para
construir e executar consultas que retornam objetos. Uma vez que um
ObjectQuery tenha sido executado ele contém
objetos tipados. A Classe ObjectQuery(Of T) - Representa uma consulta contra o armazenamento no banco de dados e é formulada por meio de uma instrução de Entidade SQL , métodos de construtor de consultas ou Language-Integrated Query (LINQ). A classe ObjectQuery representa uma consulta que retorna uma coleção objetos de entidades tipadas e sempre pertence a um contexto de objeto, no nosso caso ao contexto MacorattiEntities. Este contexto fornece a conexão e a informação necessária para compor e executar uma consulta e retorna uma instância tipada de ObjectQuery. A classe ObjectQuery suporta tanto consultas LINQ to Entities como Entity SQL contra um Entity Data Model (EDM) e implementa um conjunto de métodos construtores que podem ser usados para construir comandos de consultas que são equivalentes aos métodos do Entity SQL. |
Fazemos isso pois vamos usar consultas Entity SQL em nosso projeto.
A seguir devemos declarar a variável categoriaContexto como sendo do tipo ObjectContext:
Protected categoriaContexto As MacorattiEntitiesDevemos incluir também um controle BindingSource no formulário com o nome bs que será usado para vinculação das categorias e produtos.
Agora no evento Load do formulário inclua o seguinte código:
Private Sub frmMestreDetalhes_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'cria uma instância do ObjectContext categoriaContexto = New MacorattiEntities 'defina consulta para obter as categorias e os produtos Dim categoria As ObjectQuery = categoriaContexto.Categorias.Include("Produtos") 'atribui ao BindingSource o resultado da consulta bs.DataSource = categoria 'atribui o BindingSource ao DatagridView para exibir as categorias gdvCategoria.DataSource = bs 'Esconde a coluna Produtos (Navigation Properties) gdvCategoria.Columns("Produtos").Visible = False gdvCategoria.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells) 'Efetua a vinculação dos produtos relacionados ao segundo DataGridView gdvProdutos.DataBindings.Add(New Binding("DataSource", bs, "Produtos")) 'Esconde as colunas indicadas gdvProdutos.Columns("Categorias").Visible = False gdvProdutos.Columns("ItensPedidos").Visible = False gdvProdutos.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells) End Sub |
Vamos explicar a consulta Entity SQL usada no código:
Dim consulta As
ObjectQuery(Of Categoria) = _
categoriaContexto.Categorias.Include("Produtos")
A variável consulta é declarada como sendo do tipo ObjectQuery, que é uma classe no namespace System.Data.Objects. Dessa forma o Entity Framework irá criar e executar a consulta , usando o ObjectQuery, para retornar objetos, e esses objetos serão objetos que representam entidades no modelo conceitual (EDM) que foi gerado. Nesta consulta retornamos objetos da entidade Categoria.
Observe o comando
Include("Produtos") na consulta que usa a habilidade do EF para usar as
Navigation Properties como meio de criar vinculação entre dados
relacionados. Com isso estaremos carregando os objetos da entidade
Produto. Veja na figura ao lado mostra a entidade Categoria contendo uma Navigation Properties Produtos. |
![]() |
2- Exibindo os produtos relacionados no segundo DataGridView
Para exibir o resultado da seleção no segundo DataGridView usamos o código a seguir:
'Efetua a
vinculação dos produtos relacionados ao segundo DataGridView
gdvProdutos.DataBindings.Add(New Binding("DataSource", bs, "Produtos"))
Os dados dos produtos são acessados através da Navigation Properties da entidade Categoria onde usamos a propriedade Produtos do objeto Categoria como uma fonte de dados através do BindingSource para o controle DataGridView.
Agora no evento Click do botão - Salvar alterações no banco de dados - vamos incluir o código para persistir as alterações na base de dados:
Private Sub btnSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click Try 'salva as alterações feitas no banco de dados categoriaContexto.SaveChanges() MsgBox("Alteração salva com sucesso.") Catch ex As Exception MsgBox("Erro : " & ex.Message) End Try End Sub
|
Com isso podemos efetuar a manutenção tanto em Categorias como em Produtos e persistir as alterações feitas no banco de dados.
Simplesmente fantástico , não é mesmo !!!!
Mas não fique muito empolgado, o esquema apresentado aqui funciona porque o modelo usado é bem simples onde no relacionamento mestre-detalhe temos uma tabela representando a tabela mestre e uma tabela representando a tabela detalhe. Em relacionamentos mais complexos onde geralmente temos a utilização de Views o esquema não vai funcionar.
Outro aspecto que deve ser destacado é que ao tentar excluir um registro da tabela Mestre e salvar o resultado poderá ocorrer um erro devido ao relacionamento entre as tabelas conforme a seguir:
"The DELETE statement conflicted with the REFERENCE constraint "FK_Produtos_Categorias". The conflict occurred in database "Macoratti", table "dbo.Produtos", column "categoriaid". The statement has been terminated."
Isto indica um conflito na tabela
Produtos com a coluna Categoriaid. Para poder realizar a exclusão você terá que alterar a regra de exclusão (Delete Rule) definida para a chave estrangeira FK_Produtos_Categorias no banco de dados Macoratti.mdf definindo-a como Cascade. Após realizar esta alteração a exclusão será permitida.
|
![]() |
Como o meu objetivo nesta série de artigos é mostrar os recursos básicos do Entity Framework eu não estou preocupado com as boas práticas, estou apenas mostrando as possibilidades do framework que deverá estar mais robusto na sua segunda versão que será lançada em breve com o VS 2010.
Pegue o projeto completo aqui:
EF_Crud3.zip
Eu sei é apenas Entity
Framework , mas eu gosto.
Referências:
Entity Framework - Conceitos Básicos - Espiando o modelo conceitual
Entity Framework - Conceitos Básicos - Usando Lazy Load e Eager Load
Entity Framework - Conceitos Básicos - Incluindo, modificando e excluindo objetos
Entity Framework - Conceitos Básicos - Incluindo, modificando e excluindo objetos II
Entity Framework - Conceitos Básicos - Definindo um EDM usando a herança Table Per Type (TPT)