Entity Framework - Conceitos Básicos - Exibindo dados Relacionados


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 2 - Exibindo dados relacionados

Agora vamos a um cenário um pouco mais complexo. Imagine que você deseja apresentar em um formulário as categorias exibidas em um controle ComboBox de forma que ao selecionar uma categoria pelo seu nome os produtos relacionados serão exibidos em um controle DataGridView.

Adicione um novo formulário form2.vb no projeto e inclua neste formulário os seguintes controles : Label, Combobox e 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 os nomes das categorias no Combobox

A primeira coisa que vamos fazer é carregar o controle Combobox - cboCategorias - de forma que ele exiba o nome das categorias e que ao selecionar uma categoria pelo seu nome vamos obter o respectivo objeto Categoria.

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 MacorattiEntities

Agora no evento Load do formulário inclua o seguinte código:

 Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Try
            'cria uma instância do ObjectContext
            categoriaContexto = New MacorattiEntities
            'realiza uma consulta para retornar as categorias e os produtos ordenados por nome
            Dim consulta As ObjectQuery(Of Categoria) = _
                                    categoriaContexto.Categorias.Include("Produtos").OrderBy("it.nome")
            'exibe as categorias no combobox pelo nome
            cboCategorias.DataSource = consulta
            'exibe o nome da categoria no controle
            cboCategorias.DisplayMember = "nome"
            cboCategorias.ValueMember = "categoriaid"
        Catch ex As Exception
            MsgBox("Erro : " & ex.Message)
        End Try
    End Sub

Vamos explicar a consulta Entity SQL usada no código:

  Dim consulta As ObjectQuery(Of Categoria) = _
                                    categoriaContexto.Categorias.Include("Produtos").OrderBy("it.nome")

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.

A cláusula OrderBy("it.nome") faz com que os objetos retornados estejam ordenados alfabeticamente. O it em it.nome é um valor padrão usado em uma consulta deste tipo. Se você omitir o it a consulta não vai funcionar.

O restante do código apenas define a fonte de dados para o controle Combobox e o valor que será exibido no controle.

2- Exibindo os produtos relacionados no DataGridView

Para exibir o resultado da seleção no DataGridView vamos usar o evento SelectedIndexChanged do controle ComboBox incluindo nele o seguinte código:

  Private Sub cboCategorias_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)  _ 
          Handles cboCategorias.SelectedIndexChanged

        'Obtem o objeto para a categoria selecionada
        Dim oCat As Categoria = CType(Me.cboCategorias.SelectedItem, Categoria)
        'exibe os produtos relacionados 
        gdvProdutos.DataSource = oCat.Produtos
        'oculta as colunas indicadas
        gdvProdutos.Columns("Categorias").Visible = False
        gdvProdutos.Columns("ItensPedidos").Visible = False
        'redimensiona as colunas conforme o tamanho 
        gdvProdutos.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)

    End Sub

Quando o cliente selecionar uma categoria devemos recuperar o respectivo objeto e carregar os seus produtos.

Observe que temos que efetuar uma conversão forçada do item selecionado na combobox para o tipo Categoria.

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 para o controle DataGridView. ( gdvProdutos.DataSource = oCat.Produtos)

O resto do código apenas configura o DataGridView para exibir os dados.

Que fique bem claro que esta não é a única forma de obter esse resultado poderíamos ter usado uma consulta LINQ to Entities.

Pegue o projeto completo aqui: EF_Crud3.zip

Eu sei é apenas Entity Framework , mas eu gosto.

Referências:


José Carlos Macoratti