Entity Frameweork 4 - Apresentando os recursos da CTP5 - Code First
Esta prevista para o primeiro semestre deste ano uma nova versão do Entity Framework 4 com muitos ajustes com o objetivo de tornar a ferramenta cada vez melhor.
Enquanto a versão final não sai, vamos falar um pouco sobre uma das suas últimas atualizações, a Entity Framework Feature Community Technology Preview - CTP5, mais precisamente da funcionalidade Code-First.
Obs: Baixe a versão CTP5 aqui : http://tinyurl.com/5rg52tg
Nota: A versão anterior, a CTP4, já permitia usar o recurso do First-Code com um banco de dados existente mas exigia mais intervenção do desenvolvedor com a CTP5 tudo ficou mais simples.
A CTP5 da Entity Framewor 4 inclui atualizações para o recurso Code First e uma interface simplificada da API (DbContext)
O Entity Framework é uma ferramenta OR/M que realiza o mapeamento objeto relacional gerando entidades e mapeando-as para as tabelas do banco de dados.
Na primeira versão do Entity Framework praticamente não havia o que é conhecido como Code-First (Código Primeiro), ou seja, a possibilidade de gerar o modelo de negócios e suas entidades sem ter que primeiro criar o banco de dados antes.
Para quem trabalha usando o paradigma da orientação a objetos deveria ser natural iniciar o desenvolvimento pelo modelo de entidades, onde as classes são definidas para representar o domínio do negócio. Posteriormente, e a partir destas classes, seria gerado o banco de dados usado pela aplicação para realizar a persistência das informações.
Deveria ser assim, mas a primeira versão do EF não permitia esse recurso.
Tentando contornar este problema eram feitos certos malabarismos, mas ainda assim, havia uma dependência muito forte do mapeamento gerado pelo EF4 através do Entity Data Model, o que incomodava muita gente; até que a Microsoft liberou atualizações que permitem atualmente uma maior independência do Framework através da criação de classes POCO que não herdam das classes base geradas pelo EF.
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.Neste artigo eu vou mostrar como usar o Code-First com um banco de dados existente, mais precisamente, o banco de dados Northwind.mdf e usar os recursos da CTP5 para usar as classes POCO do nosso domínio sem ter que gerar um Entity Data Model a partir do banco de dados.
Essa é outra possibilidade, já temos um banco de dados, e vamos ainda sim usar o Code-First.Mas por que eu iria querer fazer uma coisa dessas ????
Primeiro porque eu não quero passar por todo aquele processo de ter que criar um Entity Data Model nem ter que definir um arquivo de mapeamento XML, e também porque eu quero ter um código mais limpo e conciso.
Com esse objetivo em mente vamos ao trabalho...
O que você vai precisar ter instalado na sua máquina local ?
Eu vou criar uma aplicação Web Forms usando o Visual Web Developer 2010 Express Edition.
Abra o VWD 2010 Express e no menu File selecione New Project;
A seguir escolha Visual Basic -> Web -> ASP .NET Web Application, informe o nome EF4_CodeFirst_BD e clique em OK;
Vamos incluir uma referência ao assembly da CTP5 em nosso projeto.
No menu Project clique em Add Reference;
Selecione a guia Browse e localize a dll EntityFramework na pasta onde foi instalada a CTP5 (c:\Arquivos Programas)
Os recursos da EF Code First CTP5 tem um nome de assembly atualizado e um novo namespace .NET:
Agora vamos definir as classes POCO para a nossa camada de modelo:
No menu Project clique em Add Class e informe o nome Model.vb;
A seguir digite o código abaixo para criar as classe Product, Category e Northwind:
Imports System.Data.Entity Public Class Product Public Property ProductID() As Integer Get Return m_ProductID End Get Set(ByVal value As Integer) m_ProductID = value End Set End Property Private m_ProductID As Integer Public Property CategoryID() As Integer Get Return m_CategoryID End Get Set(ByVal value As Integer) m_CategoryID = value End Set End Property Private m_CategoryID As Integer Public Property ProductName() As String Get Return m_ProductName End Get Set(ByVal value As String) m_ProductName = value End Set End Property Private m_ProductName As String Public Property UnitPrice() As System.Nullable(Of [Decimal]) Get Return m_UnitPrice End Get Set(ByVal value As System.Nullable(Of [Decimal])) m_UnitPrice = value End Set End Property Private m_UnitPrice As System.Nullable(Of [Decimal]) Public Property Discontinued() As Boolean Get Return m_Discontinued End Get Set(ByVal value As Boolean) m_Discontinued = value End Set End Property Private m_Discontinued As Boolean Public Overridable Property Category() As Category Get Return m_Category End Get Set(ByVal value As Category) m_Category = value End Set End Property Private m_Category As Category End Class Public Class Category Public Property CategoryID() As Integer Get Return m_CategoryID End Get Set(ByVal value As Integer) m_CategoryID = value End Set End Property Private m_CategoryID As Integer Public Property CategoryName() As String Get Return m_CategoryName End Get Set(ByVal value As String) m_CategoryName = value End Set End Property Private m_CategoryName As String Public Property Description() As String Get Return m_Description End Get Set(ByVal value As String) m_Description = value End Set End Property Private m_Description As String Public Property Picutre() As Byte() Get Return m_Picutre End Get Set(ByVal value As Byte()) m_Picutre = value End Set End Property Private m_Picutre As Byte() Public Overridable Property Products() As ICollection(Of Product) Get Return m_Products End Get Set(ByVal value As ICollection(Of Product)) m_Products = value End Set End Property Private m_Products As ICollection(Of Product) End Class Public Class Northwind Inherits DbContext Public Property Products() As DbSet(Of Product) Get Return m_Products End Get Set(ByVal value As DbSet(Of Product)) m_Products = value End Set End Property Private m_Products As DbSet(Of Product) Public Property Categories() As DbSet(Of Category) Get Return m_Categories End Get Set(ByVal value As DbSet(Of Category)) m_Categories = value End Set End Property Private m_Categories As DbSet(Of Category) End Class |
Note que a classe Northwind herda de DbContext.
Note também que não geramos o Entity Data Model pois vamos usar a classe DbContext.
O código acima é tudo que precisamos para criar nosso modelo e camada de acesso a dados! As CTPs anteriores a EF Code First exigiam um passo adicional para funcionarem em bancos de dados existentes (uma chamada para Database.Initializer<Northwind>(null) para que a EF Code First não criasse o banco de dados) - este passo não é mais necessário com o lançamento da CTP5.
A EF Code First permite a utilização de "POCO" - Objetos padrão da CLR - para representar as entidades dentro de um banco de dados. Isso significa que você não precisa derivar classes do modelo a partir de uma classe base, nem implementar nenhuma interface ou atributos de persistência de dados neles. Isso permite que as classes do modelo sejam mantidas limpas, facilmente testáveis, e "ignorantes quanto à persistência".
A 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. A classe Northwind acima ilustra como isso pode ser feito. Ela está mapeando nossas classes Product e Category para as tabelas "Products" e "Categories" no banco de dados. As propriedades dentro das classes Product e Category por sua vez mapeiam para colunas nas tabelas Products e Categories - e cada instância de um objeto Product/Category mapeia para uma linha dentro das tabelas.
Configurando o banco de dados
A última tarefa a realizar para poder usar o recurso da CTP5 é configurar uma string de conexão que conecte com o nosso banco de dados, no caso o Nortwhind.mdf. Para isso definimos no arquivo Web.Config (ou App.Config) a seguinte string de conexão:
<configuration> <connectionStrings> <add name="Northwind" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> |
A EF Code First usa uma convenção onde as classes DbContext por padrão procuram a string de conexão que possui o mesmo nome que a classe de contexto. Como nossa classe de contexto DbContext é chamada "Northwind" ela vai procurar a string de conexão nomeada como Northwind para usar que foi definida no arquivo Web.Config para acessar em uma instância do SQL Server o banco de dados Northwind.
Usando a camada de modelo Nortwhind
Agora podemos facilmente consultar e atualizar o nosso banco de dados usando uma camada de modelo fortemente tipada que foi construída com o CTP5 Code First.
Abra o arquivo Default.aspx e inclua nesta página um controle GridView com o nome gdvProducts e no evento Load da página inclua o seguinte código:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim northwind As New Northwind() Dim produtos = From p In northwind.Products Where p.Category.CategoryName = "Beverages" Select p gdvProducts.DataSource = produtos.ToList gdvProducts.DataBind() End Sub |
Executando o projeto iremos obter a relação de produtos exibida no GridView conforme abaixo:
Vamos agora mostrar que podemos atualizar as informações de um produto.
Altere o código do evento Load conforme abaixo onde alteramos o preço de um produto e persistimos as alterações:
Protected Sub Page_Load(ByVal
sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim northwind As New Northwind()
'localiza o produto de código igual a 1 (Chai)
'atualiza o preço do produto , seu nome e o campo discontiued
'persiste as alterações
'cria uma consulta e exibe os produtos
gdvProducts.DataSource = produtos.ToList End Sub |
Executando o projeto iremos obter novamente a relação de produtos onde podemos verificar as alterações realizadas:
Dessa forma vimos que o CTP5 EF Code First trata todas as alterações de monitoramente e trabalho e da persistência dos dados para nós de uma maneira simples (lembra que não precisamos geraro Entity Data Model ?) liberando assim o desenvolvedor para se concentrar na aplicação e na lógica do negócio ao invés de ter que se preocupar com a estrutura de acesso a dados.
Na continuação desse artigo eu irei abordar o modelo de validação embutido na CTP5 Code First. Aguarde...
Pegue o projeto completo aqui: EF4_CodeFirst_BD.zip
Referências: