Entity Framework - Gerenciando Objetos (Code-First/VB.NET)
Este artigo faz uma revisão dos conceitos básicos do gerenciamento de objetos através do Entity Framework e mostra como é simples usar o Code-First na linguagem VB .NET. |
O Entity Framework é uma extensão ao ADO .NET que é a tecnologia de acesso a dados da Microsoft que você usa para fazer a conexão e o tratamento das informações de um banco de dados específico.
O Entity Framework(EF) estende a ADO .NET abstraindo os comandos da ADO .NET pois com o EF você não vai programar para o banco de dados vai programar para objetos que foram mapeados a partir do seu modelo pelo EF. Portanto você não terá que utilizar nenhum dos objetos da ADO .NET como DataAdapter, DataReader, DataSet, DataTable, etc. nem comandos SQL como SELECT/INSERT/UPDATE quem vai fazer isso para você será o EF.
O EF permite que isso ocorra fazendo a abstração do modelo do banco de dados e realizando o mapeamento objeto relacional entre o modelo conceitual de objetos e o modelo físico que é o banco de dados.
O EF já esta integrado ao Visual Studio 2010 e às versões Express (VB.NET e C#) e portanto você não tem que instalar nada para usar o Entity Framework apenas o provider do banco de dados que você deseja usar.
Na figura abaixo temos um esquema básico do funcionamento do EF:
Além de simplificar a
codificação reduzindo a quantidade de código que você
tem que produzir o EF
permite a utilização do recurso Intellisense o que
torna ainda mais produtivo a sua utilização e evita
que você cometa erros de sintaxe ou tenha que se lembrar
de nomes de recursos(nome da tabela, campo,etc.) O EF utiliza o ADO .NET Data Provider que é suportado pela maioria dos principais SGBD do mercado como SQL Server, Oracle, MySQL, FireBird , etc. Veja a relação de providers disponíveis em : http://msdn.microsoft.com/en-us/data/dd363565.aspx Para conhecer os .NET
Framework Data Providers (ADO.NET) veja este link: |
A partir da Versão 4.1 do Entity Framework temos a abordagem Code First e a nova API DbContext. Esta API fornece uma interface mais produtiva para trabalhar com o Entity Framework e pode ser usada com o seguintes padrões de desenvolvimento:
As classes POCO - 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. |
A API DbContext nada mais é do que uma abstração simplificada do ObjectContext e diversos outros tipos introduzidos nas versões anteriores do Entity Framework. Esta API é otimizada para realizar as tarefas mais comuns e dar suporte a padrões de código como "Unit Of Work Pattern" e "Repository Pattern". A API DbContext é um invólucro para ObjectContext e além disso contém: Um conjunto de APIs que são mais fáceis de usar do que a exposta pelo ObjectContext e APIs que permitem utilizar o recurso do Code-First e as convenções;
Obs: Para que você se familiarize com os conceitos básicos do Entity Framework veja os artigos da seção Entity Framework do site Macoratti.net. Boa parte dos conceitos já abordados em outros artigos são repetidos aqui.
O recurso Code First do EF permite que você crie primeiro as classes POCO que a partir delas o seu banco de dados seja gerado de forma automática. Ele faz isso usando um container que chamamos de Contexto e que faz o mapeamento das classes criadas com o banco de dados e que usando convenções (que podemos controlar) gera o banco de dados e as tabelas através desse mapeamento.
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 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.
Podemos usar Code First e
apontar para um banco de dados existente ao invés
de criar o banco de dados.(Este padrão é conhecido
como DataBase First) A maneira mais fácil de de usar
o Code First com um banco de dados existente é
adicionar uma string de conexão ao arquivo App.Config ou arquivo Web.Config (para aplicações ASP .NET) que
tenha o mesmo nome do seu DbContext derivado. Exemplo: <connectionStrings> |
Neste artigo eu vou utilizar o Visual Basic 2010 Express Edition e mostrar como podemos usar o Entity Framework e o recurso Code First para criar o banco de dados e a tabela a partir da definição da classe POCO. Vou mostrar também como podemos gerenciar os objetos gerados pelo mapeamento para tratarmos as informações do banco de dados.
Abra o Visual Basic 2010 Express Edition e crie um novo projeto do tipo Windows Forms Application com o nome GerenciandoObjetos_EF;
Com a solução criada vamos incluir nossa primeira classe POCO no projeto que irá representar uma tabela do banco de dados.
No menu Project clique em Add Class e informe o nome Cliente.vb;
A seguir inclua o seguinte código nesta classe:
Imports
System.ComponentModel.DataAnnotations Imports System.ComponentModel.DataAnnotations.Schema
<Table("Clientes")> |
Observe que definimos uma classe chamada Cliente com três propriedades : Id, nome e email
Essa classe será mapeada pelo EF através do contexto que iremos criar em seguida para gerar a tabela Cliente no banco de dados da aplicação que também será criado pelo EF.
Vamos agora definir a classe para o nosso contexto. Essa classe deverá herdar de DbContext e deverá definir uma propriedade do tipo DbSet().
O EF Code First permite que você conecte facilmente suas classes POCO do modelo em um banco de dados através da criação de uma classe "DbContext" que expõe propriedades públicas que mapeiam para tabelas do banco de dados.
No menu Project clique em Add Class e informe o nome Contexto.vb;
Imports System.Data.Entity Public Class ClientesDB Inherits DbContext Public Property Clientes() As DbSet(Of Cliente) End Class |
Vejam como é simples. Definindo apenas essas duas classes já podemos partir para o gerenciamento dos objetos através do código usando o EF.
No formulário form1.vb que vamos definir uma interface bem simples pois nosso objetivo é mostrar como podemos usar o EF para gerenciar os objetos realizando as operações de consulta, alteração, exclusão e inclusão.
Inclua a partir da Toolbox no formulário form1.vb os seguintes controles:
Conforme o leiaute da figura abaixo:
Agora vamos definir o código usando o evento Click de cada um dos botões de comando:
1- Botão de comando Incluir:
Private Sub btnIncluirObjeto_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIncluirObjeto.Click Dim db As New ClientesDB Dim cli As New Cliente() With { _ .nome = "Macoratti", _ .email = "macoratti@yahoo.com" _ } 'Use (ObjectSet <TEntity> .AddObject()) 'Use (ObjectContext.AddObject()) 'Use (EntityCollection <TEntity> .Add()) db.Clientes.Add(cli) db.SaveChanges() ConsultaObjetos(db) End Sub |
A primeira coisa que devemos fazer é criar uma instância do nosso contexto : Dim db As New ClientesDB
A seguir criamos uma instância da classe Cliente e atribuímos os valores para as propriedades nome e email;
Para adicionar novos objetos ao conjunto de entidades(Entity Set), você deve criar uma instância de um Entity Type e adicionar o objeto para o object context.Os Objetos ligados ao contexto do objeto são gerenciados por esse contexto de objeto.
Você pode adicionar novos objetos a
um object context usando um dos seguintes métodos:
1- O método
AddObject no ObjectSet.
2- O método AddObject em ObjectContext.
3- O método Add no EntityCollection.
Para entidades Entity Framework geradas e objetos proxy POCO, as
entidades adicionadas estão ligados ao contexto em que o objeto
principal está ligado. Entidades POCO estão ligadas quando o
método DetectChanges for chamado.
As seguintes considerações se aplicam quando da inclusão de objetos:
2- Rotina ConsultaObjetos
Private Sub ConsultaObjetos(ByVal _db As ClientesDB) lstObjetos.Items.Clear() Dim clientes = _db.Clientes For Each c In clientes lstObjetos.Items.Add(c.Id & "-" & c.nome & "-" & c.email) Next End Sub |
Esta rotina recebe uma instância do contexto criado e exibe no controle ListBox os valores para as propriedades id, nome e email do objeto.
3- Botão de comando Alterar:
Private Sub bntAlterarObjeto_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bntAlterarObjeto.Click Dim db As New ClientesDB Dim c As Cliente = db.Clientes.First(Function(i) i.Id = 1) c.email = "macoratti@ig.com.br" db.SaveChanges() ConsultaObjetos(db) End Sub |
Quando qualquer propriedade escalar ou complexa de um objeto é alterada, o estado do objeto da entidade de nível superior é alterado para Modified.
As alterações não são rastreadas quando os objetos estão em um estado Detached. Os Objetos estão neste estado quando retornados por uma consulta que usa a opção NoTracking ou após serem detached de uma ObjectContext chamando o comando Detach.
Obs: Quando você muda uma associação de uma chave estrangeira, o estado do objeto muda para Modified. Quando você altera uma associação independente, o estado do objeto dependente não muda.
No código estamos usando uma expressão lambda para obter o cliente com código igual a 1 e em seguida alteramos o seu email :
Dim c As
Cliente = db.Clientes.First(Function(i) i.Id = 1)
c.email
= "macoratti@ig.com.br"
O método SaveChanges efetiva as alterações persistindo-as no banco de dados.
4- Botão de comando Deletar:
Private Sub btnDeletarObjeto_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeletarObjeto.Click Dim db As New ClientesDB Dim c As Cliente = db.Clientes.First(Function(i) i.Id = 3) db.Clientes.Attach(c) db.Entry(c).State = EntityState.Deleted db.SaveChanges() ConsultaObjetos(db) End Sub |
No código localizamos o cliente com id igual a 3, anexarmos o cliente ao Contexto e em seguida alteramos o seu estado para Deleted;
Dim c As
Cliente = db.Clientes.First(Function(i) i.Id = 3)
db.Clientes.Attach(c)
db.Entry(c).State
= EntityState.Deleted
O método SaveChanges efetiva a exclusão persistindo-a no banco de dados.
5- Código do evento Load
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim db As New ClientesDB ConsultaObjetos(db) End Sub |
Aqui apenas criamos uma instância do contexto e chamamos a rotina ConsultaObjetos() para exibir os objetos no ListBox.
Finalmente o código do botão Sair encerra a aplicação:
Private Sub btnSair_Click(sender As System.Object, e As System.EventArgs) Handles btnSair.Click Application.Exit() End Sub |
Executando o projeto e acionando cada um dos botões de comando iremos obter o seguinte resultado:
Usando o SQL Server Management Studio podemos verificar o banco de dados, as tabelas e os registros incluídos, alterados e excluídos:
Observe que o nome banco de dados é composto pelo nome da solução + o nome da classe definida no contexto : GerenciandoObjetos_EF + ClientesDB
Você percebeu que sem usar nenhuma ferramenta para banco de dados. nenhum comando SQL, sem se preocupar com objetos ADO .NET e apenas definindo classes POCO conseguimos criar o banco de dados, a tabela e gerenciar as informações através do gerenciamento os objetos via Entity Framework.
Pegue o projeto completo aqui: GerenciandoObjetos_EF4.1.zip
Heb 3:5
Moisés, na verdade, foi fiel em toda a casa de Deus, como servo, para testemunho das coisas que se haviam de anunciar;Heb 3:6
mas Cristo o é como Filho sobre a casa de Deus; a qual casa somos nós, se tão-somente conservarmos firmes até o fim a nossa confiança e a glória da esperança.Heb 3:7
Pelo que, como diz o Espírito Santo: Hoje, se ouvirdes a sua voz,Heb 3:8
não endureçais os vossos corações, como na provocação, no dia da tentação no deserto,Heb 3:9
onde vossos pais me tentaram, pondo-me à prova, e viram por quarenta anos as minhas obras.Referências: