Entity Framework 4.0 - DataBinding com Windows Forms e WPF


A nova versão do Visual Studio, o Visual Studio 2010, lançado no final de abril trouxe dentre muitas novidades a tão esperada versão do Entity Framework, que passou a ser identificada como Entity Framework 4.0.

Segue abaixo um resumo das principais novidades desta versão do Entity Framework:

  • Persistence Ignorance - A Persistence Ignorance significa que podemos definir uma camada de domínio que contém entidades que são independentes do mecanismo de persistência usado. O EF4 agora permite que definimos nossos próprios POCO (Plain Old CLR Object), que são desacoplados de qualquer persistência específica. (O NHibernate já oferecia este recurso.)
  • T4 Code Generation - (Text Template Transformation ToolKit) é um modelo para gerar código que você pode usar para gerar código no EF4. Foram incluídos diversos modelos T4 para POCO (estão disponíveis junto a opção Add Code Generation item...)
  • Lazy Loading - Lazy Loading é o mecanismo utilizado pelos frameworks de persistência para carregar informações sobre demanda. Agora o EF4 da suporte a este recurso. Na versão anterior você tinha que usar o include explicitamente para realizar o lazy loading.
  • Model-First development - O Model-First permite a geração do banco de dados a partir do modelo de entidades no próprio Visual Studio.
  • Essas novidades tornaram a utilização do EF4 mais fácil e aproximando-o mais do seu concorrente mais famoso o NHibernate.

    Vejamos a seguir quais as principais operações que são realizadas na utilização do EF4 em uma aplicação com acesso a dados:

    Criando o modelo de entidades - Entity Data Model (EDM)

    O objetivo da ADO .NET Entity Framework é mais ambicioso; o serviço OR/M seria apenas mais um serviço e outros serviços como relatórios, sincronização, backup, etc. também seriam oferecidos; para cobrir todos estes serviços foi criado um modelo de dados que é similar ao usado no paradigma orientado a objetos que o desenvolvedor utiliza, e também é independente de qualquer linguagem ou plataforma.

    Este modelo de dados é conhecido como Entity Data Model (EDM) ou modelo de entidades de dados e pode ser considerado o coração da do Entity Framework.

    O EDM é um modelo entidades-relacionamentos onde :
    • Entidades - são instâncias de tipos de entidades como Clientes, Produtos os quais estão estruturados em registros e chaves;
    • Relacionamentos - são instâncias de tipos de relacionamentos que são associações entre duas ou mais tipos de entidades;

    É a partir do modelo de entidades que podemos escrever código usando as diferentes APIs , como o provedor EntityClient ou o Object Services com LINQ to Entities.

    O Visual Studio oferece um assistente para a criação do EDM a partir do seu banco de dados ou do seu modelo de entidades.

    Para criar um EDM a partir de um banco de dados relacional podemos usar o Visual Studio 2010, o VB 2010 Express Edition ou o Visual C# 2010 Express Edition.

    Após criar um projeto Windows Forms, Web Application, WPF Application, etc. e a seguir clique com o botão direito sobre o nome do projeto e selecione Add -> New Item e na janela Add New Item selecione Data -> ADO .NET Entity Data Model e informe o nome Northwind.edmx pois vamos gerar o modelo de entidades a partir do banco de dados Northwind.mdf;

    O assistente irá apresentar a tela do Entity Data Model Wizard onde temos as opções de gerar o modelo a partir do banco de dados ou de um modelo vazio;

    Vamos gerar o modelo a partir do banco de dados Northwind.mdf portanto selecione o item Generate from database e clique em Next>;

    O assistente irá apresenta a janela para você escolher a conexão. Definindo a conexão para o Northwind.mdf vemos a string de conexão da entidade e nome com a qual ela será salva no arquivo App.Config;

    Na próxima janela vamos escolher quais tabelas do banco de dados irão fazer parte do modelo de entidades e para as quais será gerado o mapeamento objeto relacional;

    Eu vou selecionar apenas as tabelas Categories e Products para fica mais fácil visualizar o modelo;

    Ao final será gerado o arquivo Northwind.edmx que representa o modelo de entidades. No descritor podemos ver as entidades, o mapeamento gerado pelo EF4;

     

    Com isso estamos prontos para usar o modelo de entidades gerado.

    Trabalhando com o EDM gerado

    Agora que o temos o EDM gerado podemos acessar os dados de forma bem simples pois o EF gerou as entidades e todo o mapeamento com as tabelas do banco de dados criando um contexto a partir do qual temos os métodos para acessar, editar e excluir as informações das entidades persistindo-as no banco de dados.

    Com isso você não vai precisar mais usar os objetos ADO .NET para abrir e fechar conexões nem acessar os dados nem com comandos SQL para realizar as tarefas básicas de manutenção de dados.

    A partir deste momento você tem acesso ao modelo de entidades e pode realizar consultas usando o LINQ to Entities obtendo listas de objetos e objetos e usando uma sintaxe bem mais próxima da linguagem de alto nível que estamos usando.

    Windows Forms - DataBinding com exibição mestre-detalhes

    Vamos realizar o databinding em um formulário Windows Forms para uma exibição Mestre-Detalhes das tabelas Categories e Products visto que temos um relacionamento um-para-muitos onde uma categoria pode conter muitos produtos.

    Vamos usar o Visual Basic 2010 Express Edition e criar um novo projeto Windows Forms Application com o nome EF4_WF_DataBinding;

    A seguir clique com o botão direito sobre o nome do projeto e selecione Add -> New Item e na janela Add New Item selecione Data -> ADO .NET Entity Data Model e informe o nome Northwind.edmx pois vamos gerar o modelo de entidades a partir do banco de dados Northwind.mdf conforme descrito no início do artigo;

    Ao final devemos ter o formulário form1.vb e o EDM Northwind.edmx no projeto;

    Inclua dois controles no formulário form1.vb :

    Conforme o leiaute da figura a seguir:

    Agora vamos ao código :

    No evento Load do formulário inclua o código que irá preencher o controle ComboBox exibindo os nomes das categorias:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Using ctx = New NORTHWNDEntities
                cboCategorias.DataSource = ctx.Categories.ToList()
                cboCategorias.ValueMember = "CategoryID"
                cboCategorias.DisplayMember = "CategoryName"
            End Using
    
     End Sub

    Agora no evento SelectedIndexChanged do controle Combobox vamos incluir o código que irá preencher o controle DataGridView com os produtos para a categoria selecionada;

        Private Sub cboCategorias_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCategorias.SelectedIndexChanged
            Dim iCatID As Integer = 0
            Try
                If (Integer.TryParse(cboCategorias.SelectedValue.ToString(), iCatID)) Then
                    Using ctx = New NORTHWNDEntities
                        Dim produtos = From p In ctx.Products
                                               Where p.CategoryID = iCatID
                                               Select p
                        gdvProdutos.DataSource = produtos.ToList()
                    End Using
                End If
            Catch ex As Exception
                MsgBox(" Erro " & ex.Message)
            End Try
        End Sub

    Este código obtém o id da categoria selecionada e defina uma consulta LINQ (observe que não estamos usando o caractere (_) para indica quebra de linha):

    Dim produtos = From p In ctx.Products
                          Where p.CategoryID = iCatID
                          Select p

    Executando o projeto iremos obter:

    Simples, simples assim...

    Windows Presentantion Foundation (WPF) - DataBinding com exibição mestre-detalhes

    Vamos agora realizar a mesma tarefa feita acima para um projeto WPF.

    Vamos continuar a usar o Visual Basic 2010 Express Edition e criar um novo projeto WPF Application com o nome EF4_WPF_DataBinding;

    A seguir clique com o botão direito sobre o nome do projeto e selecione Add -> New Item e na janela Add New Item selecione Data -> ADO .NET Entity Data Model e informe o nome Northwind.edmx pois vamos gerar o modelo de entidades a partir do banco de dados Northwind.mdf conforme descrito no início do artigo;

    No descritor WPF inclua dois controles em MainWindow.xaml a partir da ToolBox:

    Conforme o leiaute abaixo:

    Agora a no menu Data selecione a opção Show Data Sources;

    A seguir Arraste e solte Categories para ListBox e Products, vinculado a Categories, para o DataGrid;

    Observe que após arrastar e soltar os itens da fonte de dados (Data Sources) o código XAML é gerado automaticamente:

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="EF4 - DataBinding - Mestre Detalhes" Height="372" Width="506" mc:Ignorable="d" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:EF4_WPF_DataBinding">
        <Window.Resources>
            <CollectionViewSource x:Key="CategoriesViewSource" d:DesignSource="{d:DesignInstance my:Categories, CreateList=True}" />
            <CollectionViewSource x:Key="CategoriesProductsViewSource" Source="{Binding Path=Products, Source={StaticResource CategoriesViewSource}}" />
        </Window.Resources>
        <Grid DataContext="{StaticResource CategoriesViewSource}">
            <ListBox Height="91" HorizontalAlignment="Left" Margin="27,25,0,0" Name="ListBox1" VerticalAlignment="Top" Width="239" 
    DisplayMemberPath="CategoryName" ItemsSource="{Binding}" SelectedValuePath="CategoryID" />
            <DataGrid AutoGenerateColumns="True" Height="162" HorizontalAlignment="Left" Margin="27,147,0,0" Name="DataGrid1" 
    VerticalAlignment="Top" Width="432" ItemsSource="{Binding Source={StaticResource CategoriesProductsViewSource}}" />
            <Label Content="Selecione uma Categoria" Height="28" HorizontalAlignment="Left" Margin="27,0,0,0" Name="Label1" VerticalAlignment="Top" />
            <Label Content="Produtos" Height="28" HorizontalAlignment="Left" Margin="27,122,0,0" Name="Label2" VerticalAlignment="Top" />
        </Grid>
    </Window>
    

    Executando o projeto iremos obter:

    Simples, simples assim...

    Pegue os projetos completos aqui: EF4_WF_DataBinding.zip e EF4_WPF_DataBinding.zip

    Eu sei é apenas Entity Framework 4, mas eu gosto...

    Referências:

    José Carlos Macoratti