WPF - DataBinding com Entity Framework 4.1 e Code First - I


 

Hoje vamos abordar novamente os recursos do Code First do Entity Framework 4.1 dessa vez em uma aplicação WPF onde iremos usar tipos definidos no modelo como fonte de dados em uma apresentação mestre-detalhes.

 

A versão 4.1 do Entity Framework trouxe grandes melhorias em relação a versão anterior como:

  • Suporte a POCO: Agora você pode definir as entidades sem a necessidade de classes base ou atributos de persistência de dados;
  • Suporte a Lazy Loading (carregamento tardio): Agora você pode carregar sub-objetos de um modelo sob demanda, ao invés de carregá-los antecipadamente;
  • Suporte a N-Camadas e Auto-Rastreamento de Entidades: Trata cenários nos quais as entidades são passadas entre camadas ou chamadas web sem estado;(stateless)
  • Melhor suporte para Geração de SQL e SPROC: ) EF4 executa um código SQL melhorado, e inclui uma integração melhor com SPROCs (stored procedures - procedimentos armazenados);
  • Suporte à Pluralização Automática: o EF4 inclui suporte à pluralização automática de tabelas Ex: Produtos -> Produto);
  • Testabilidade Melhorada: O objeto de contexto do EF4 pode agora ser mais facilmente imitado usando interfaces;
  • Suporte melhorado para os Operadores LINQ: o EF4 agora oferece suporte completo para os operadores LINQ;

fonte: ScottGu's Blog

 

Na primeira versão do Entity Framework praticamente não havia o que é conhecido como Code-First (Código Primeiro ou Antecipado), ou seja, a possibilidade de gerar o modelo de negócios e suas entidades sem ter que primeiro criar o banco de dados.

Quando decidimos usar o Code-First não precisamos começar nossa aplicação criando o banco de dados ou definindo um esquema mas podemos iniciar escrevendo classes .NET (POCO) para definir o modelo de objetos do nosso domínio sem ter que misturar a lógica de persistência de dados com as classes de negócio.

O Entity Framework por padrão adota algumas convenções (Conventions) que ele usa para realizar algumas operações como a criação do banco de dados e tabelas e definição de nomes, chaves primárias, etc.

POCO - Plain Old CLR Object - são classes simples de domínio que possuem apenas get/sets e um construtor e que não dependem de nenhum framework; 
as classes POCO não são obrigadas a herdar de nenhuma outra classe ou implementar nenhuma interface.Portanto as classes POCO  são independente de frameworks.

 

No exemplo deste artigo vamos definir um modelo com dois tipos que participam em um relacionamento um-para-muitos:

Os recursos necessários para acompanhar o artigo são:(todas as versões usadas são grátis e podem ser baixadas nos links abaixo)

Criando a estrutura da solução

 

Passo 1 - Criando a solução e o projeto onde residirá o nosso modelo e a referência ao Entity Framework e o Code-First:

 

Abra o Visual Basic 2010 Express Edition e no menu File clique em New Project;

 

Selecione a linguagem Visual Basic e o modelo Class Library; informe o nome EscolaModel e clique em OK;

 

No menu File clique em Save All;

Na janela Save Project informe em :

Passo 2 - Criando o projeto WPF

No menu FIle clique em Add e a seguir em New Project;

Selecione a linguagem Visual Basic e o modelo WPF Application e informe o nome WPF_Interface e clique em OK;

Ao final na janela Solution Explorer você deverá ver uma solução contendo dois projetos conforme a figura abaixo:

Definindo o modelo

Vamos agora trabalhar com o projeto EscolaModel e definir o modelo que iremos usar em nossa aplicação WPF.

O nosso modelo simplificado pode ser visto no diagrama de classes a seguir:

O nosso modelo de negócio consiste de duas classes:
  • Curso
  • Aluno

O modelo de classes representa um Curso que possui 1 ou mais alunos.

Temos aqui uma associação que representa o relacionamento um-para-muitos.

O relacionamento um-para-muitos é usado quando uma entidade A pode se relacionar com uma  ou mais entidades B.  Este relacionamento é representado pelo sinal: 1:N ou 1: *que expressa a cardinalidade do relacionamento.

A cardinalidade é um conceito importante para ajudar a definir o relacionamento, ela define o número de ocorrências em um relacionamento. Para determinar a cardinalidade, deve-se fazer a pergunta relativa ao relacionamento em ambas as direções. No exemplo a seguir, temos

Vamos usar o Entity Framework 4.1 e o modelo de desenvolvimento Code-First escrevendo as classes POCO que definem o nosso modelo conceitual. As classes não precisam derivar de qualquer classe base nem implementar alguma interface.

 

No projeto EscolaModel clique com o botão direito do mouse e selecione Add Reference;

 

A seguir selecione a guia Browse da janela Add Reference e localize o arquivo EntityFramework.dll na pasta onde você instalou o Entity Framework 4.1;

 

 

Agora altere o nome da classe class1.vb para EscolaModel.vb e digite o código abaixo que define as nossas classes do domínio: Curso e Aluno:

 

Nota: Para simplificar eu estou criando as classes Curso e Aluno no arquivo EscolaModel.vb mas poderia criar em arquivos distintos.

 

Imports System.ComponentModel
Imports System.Collections.ObjectModel
Public Class Curso
    Public Sub New()
        Me.Aluno = New ObservableCollection(Of Aluno)()
    End Sub
    'chave primaria
    Private _cursoID As Integer
    Public Property CursoID() As Integer
        Get
            Return _cursoID
        End Get
        Set(value As Integer)
            _cursoID = value
        End Set
    End Property

    Private _nome As String
    Public Property Nome() As String
        Get
            Return _nome
        End Get
        Set(value As String)
            _nome = value
        End Set
    End Property
    'propriedade de navegação
    Private _Alunos As ObservableCollection(Of Aluno)
    Public Property Aluno() As ObservableCollection(Of Aluno)
        Get
            Return _Alunos
        End Get
        Private Set(value As ObservableCollection(Of Aluno))
            _Alunos = value
        End Set
    End Property
End Class
Public Class Aluno
    'chave primaria
    Private _alunoID As Integer
    Public Property AlunoID() As Integer
        Get
            Return _alunoID
        End Get
        Set(value As Integer)
            _alunoID = value
        End Set
    End Property
    Private _nomeAluno As String
    Public Property NomeAluno() As String
        Get
            Return _nomeAluno
        End Get
        Set(value As String)
            _nomeAluno = value
        End Set
    End Property
    Private _email As String
    Public Property Email() As String
        Get
            Return _email
        End Get
        Set(value As String)
            _email = value
        End Set
    End Property
    ' chave estrangeira
    Private _cursoID As Integer
    Public Property CursoID() As Integer
        Get
            Return _cursoID
        End Get
        Set(value As Integer)
            _cursoID = value
        End Set
    End Property
    'propriedade de navegação
    Private _Curso As Curso
    Public Overridable Property Curso() As Curso
        Get
            Return _Curso
        End Get
        Set(value As Curso)
            _Curso = value
        End Set
    End Property
End Class
A propriedade Alunos na classe Curso e a propriedade Curso na classe Aluno são as propriedades de navegação que fornecem uma maneira de navegar através de uma associação ou relacionamento entre duas entidades retornando uma referência para um objeto (se a multiplicidade e um ou zero-ou-um) ou uma coleção (se a multipliciade é muitos).

 

O Entity Framework nos dá a opção de carregar as entidades relacionadas a partir do banco de dados de forma automática sempre que acessarmos a propriedade de navegação.

 

Com este tipo de carga de objetos (conhecido como lazy loading) esteja atento que cada propriedade de navegação que for acessada resultará em um consulta separada executada no banco de dados se a entidade ainda não estiver no contexto.

 

Quando usamos classes POCO para definir as nossas entidades o lazy loading é ativado pela criação de instâncias de tipos proxy derivados em tempo de execução que então sobrescreve as propriedades virtuais para incluir a lógica lazy loading.

 

 

 

 

Definindo uma classe derivada DBContext que suporta o  nosso modelo de entidades


Para começar a usar os objetos da entidades para acesso a dados precisamos do contexto dos objetos definido em : System.Data.Entity.DbContext ou em System.Data.Objects.ObjectContext

 

Podemos então definir uma classe que deriva de DbContext ou de ObjectContext e exponha as propriedades de System.Data.Entity.DbSet ou de System.Data.Objects.ObjectSet para as entidades definidas no modelo.

 

DbContext e DbSet são um invólucro para ObjectContext e ObjectSet e fornecem uma API simplificada que podemos usar para realizar as tarefas comuns e que permitem que continuemos acessando os tipos que vamos precisar.

 

Vamos incluir uma nova classe no projeto EscolaModel clicando sobre o projeto com o botão direito do mouse;

 

Clique em Add a seguir em Class e escolha o modelo Class informando o nome EscolaModelEntidades.vb e clique no botão Add;

 

 

A seguir digite o código a seguir que cria a classe EscolaEntidades que herda de DbContext :

 

Imports System.Data.Entity
Partial Public Class EscolaEntidades
    Inherits DbContext
    Public Sub New()
    End Sub
    Private _Cursos As DbSet(Of Curso)
    Public Property Cursos() As DbSet(Of Curso)
        Get
            Return _Cursos
        End Get
        Set(value As DbSet(Of Curso))
            _Cursos = value
        End Set
    End Property
    Private _alunos As DbSet(Of Aluno)
    Public Property Alunos() As DbSet(Of Aluno)
        Get
            Return _alunos
        End Get
        Set(value As DbSet(Of Aluno))
            _alunos = value
        End Set
    End Property
End Class
A classe DbContext permite o acesso mais fácil a consultas e permite trabalhar com os dados das entidades como objetos.

 


Este código usa uma abordagem de "convenção sobre configuração". Nessa abordagem você confia em convenções de mapeamento comuns, em vez de explicitamente configurar o mapeamento. Por exemplo, se uma propriedade em uma classe contém a string "ID" ou "Id", ou o nome da classe seguido por Id (Id pode ser qualquer combinação de letras maiúsculas e minúsculas) o Entity Framework trata essas propriedades como chaves primárias por convenção.

Essa abordagem funciona na maioria dos cenários de mapeamento de banco de dados comum, mas o Entity Framework fornece maneiras para que você possa substituir essas convenções. Por exemplo, se você deseja explicitamente definir uma propriedade para ser uma chave primária, você pode usar data annotations.

 

Dessa forma definimos as nossas entidades do modelo usando os recursos do Entity Framework no modelo de desenvolvimento Code-First.

 

Na segunda parte do artigo irei criar a aplicação WPF e realizar a vinculação de dados (databinding) no modelo mestre-detalhes:

WPF - DataBinding com Entity Framework 4.1 e Code First - II

 

"Como esta escrito: Não há um justo, nem um sequer. Não há ninguém que entenda; não há ninguém que busque a Deus." Rom. 10-11

Referências:


José Carlos Macoratti