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:
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:
Curso (principal)
Aluno (dependente)
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:
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: