Entity Framework Code First

Olá pessoal, quanto tempo em?

Voltando aqui para falar um pouco sobre o Code First, uma nova feature do Microsoft ADO.Net Entity Framework 4.1, que poderá ser baixado do site: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8363 ou de outras formas que eu irei falar mais para frente 🙂

Code First, O que é ?

  1. A tecnologia de Mapeamento Objeto-Relacional(O/RM) da Microsoft fornece uma série de abordagens para o desenvolvimento de aplicações, ou seja, resolver um dos questionamentos do que virá primeiro, o banco de dados ou a aplicação. Para isto o Entity Framework nós fornece três possibilidades:
  • Database First: A partir de um banco de dados já existente, o Entity Framework irá realizar o mapeamento das tabelas e criar o as entidades correspondentes.
  • Model First: Introduzido na Framework 4.0, o Model First permite que seja criado primeiramente o mapeamento relacional da aplicação através da ferramenta gráfica do Visual Studio para que então seja criado o banco de dados da aplicação.
  • Code First: Eis nosso foco, a nova feature da Entity Framework que permite que através das classes da aplicação que representam as entidades de negócio seja possível manipular dados sem que um banco de dados já exista. Ou seja, através de uma aplicação nova ou já existente que contem uma série de classes POCO (Plain Old CLR Objects, leia mais em: http://blogs.msdn.com/b/efdesign/archive/2008/06/24/initial-poco-design-1-pager.aspx) é possível deixar para a Framework o trabalho de criar o banco, tabelas e mapeamento baseado na estrutura de classes da sua aplicação, incrível não é
Exemplo:
Inicialmente, vamos criar uma aplicação simples, somente para demonstrar com instalar e utilizar o Code First integrado ao Entity Framework, Para instalar o Entity Framework 4.1 e referenciar o projeto, irei utilizar o gerenciador de pacote NuGet (http://nuget.codeplex.com/)
Para isso, vamos criar um um Projeto Web Vazio, com o nome de MyCodeFirst, conforme a Figura 1

Criando Projeto MyCodeFirst

Definindo as classes POCO

Agora com o projeto criado, vamos criar nossas entidades Poco, para esse primeiro exemplo, vamos criar um conjunto de classes que armazenem dados sobre carros, motos e caminhões. Para isto, teremos as classe Marca, Modelo, uma classe abstrata Veiculo e três classes que à herdam. Segue na Figura 2 o diagrama de classe da nossa aplicação:

Diagrama de Classe POCO

Segue abaixo na listagem 1, o código de criação das entidades:

namespace MyCodeFirst
{
    public class Marca
    {
        public int MarcaId { get; set; }
        public string Nome { get; set; }
    }
    public class Modelo
    {
        public int ModeloId { get; set; }
        public string Nome { get; set; }
        public Marca Marca { get; set; }
    }
   public class Carro
    {
        public int CarroId { get; set; }
        public Modelo Modelo { get; set; }
        public int AnoFabricacao { get; set; }
        public int AnoModelo { get; set; }
        public int QtdRodas { get; set; }
        public string Cor { get; set; }
    }
}

Referenciando o Entity Framework 4.1 

Nossas classes já estão criadas, agora vamos adicionar a referência do Entity Framework 4.1 ao nosso projeto, para isto, vamos clicar com o botão direito sobre o projeto e então clicar em Manage NuGet Packages, Conforme a Figura 3

Nova Opção para Adicionar Referências

Na tela do Manage NuGet Packages, espere ele terminar de listar todos os pacotes, procure por EFCodeFirst e então clique em Install. O download da biblioteca será feito e você deverá confirmar a licença de utilização. Este processo poderá demorar um pouco. Por fim, você verá que foi baixado e instalado em sua aplicação a referência ao Entity Framework 4.1.

Tela de Seleção do NuGet Package

Criando a Classe de Contexto

Para quem já trabalhou com Entity Framework, utilizando um arquivo de mapeamento, sabe que o contexto é a classe que, além de várias outras funções, é responsável por gerenciar as conexões com o banco de dados, servir de proxy para realização de consultas e alteração e inserção de dados fazendo a montagem das entidades, etc.

Para o Code First, a classe de contexto é a classe que e irá informar para a aplicação, o que será mapeado para o banco de dados, qual e como acessar este banco de dados e quais ações deverão ser feitas para realizar este mapeamento (inclusive criar o próprio banco de dados) .

Para criar-mos nossa classe de contexto, devemos criar uma nova classe que herde a classe DbContext que encontra-se no namespace System.Data.Entity.

Agora que criamos a classe de contexto vamos informar o que será mapeado, isto deverá ser feito criando uma propriedade do tipo DbSet e informando via parâmetro genérico as entidades que serão mapeada. Veja abaixo na Listagem 2 como a classe ficará:

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace MyCodeFirst
{
    public class AutomoveisContext:DbContext
    {
        public DbSet<Carro> Carros { get; set; }
        public DbSet<Marca> Marcas { get; set; }
        public DbSet<Modelo> Modelos { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }
}
A sobreposição do método OnModelCreating é uma forma de poder controlar alguns detalhes que  envolvem a criação do modelo no banco de dados e do mapamento, por exemplo inibir a pluralização do nome das tabelas.
Definindo a String de Conexão
Agora que já temos a classe de contexto pronta, vamos informar a aplicação, como ela irá se comunicar com o banco de dados.
Este passo não é verdadeiramente necessário caso a instalação do Visual Studio tenha sido a default, instalando também o Microsoft SQL Server 2005/2008 Express em uma instância nomeada de SqlExpress. O CodeFirst irá detectar que nenhuma string de conexão foi informada e irá criar uma conexão ao seu banco de dados, criando um banco com o nome da classe de contexto.
Caso esse não seja o caso, ou você deseje controlar isso, basta adicionar ao web.config uma string de conexão com o mesmo nome da classe de contexto, conforme exemplo abaixo na Listagem 3:

<connectionStrings>
  <add name ="AutomoveisContext"
       connectionString="Data Source=.\sqlexpress;Initial Catalog=AutomoveisDB;Integrated Security=True;MultipleActiveResultSets=True"
       providerName="System.Data.sqlClient"/>
</connectionStrings>

Testando a Aplicação

Agora que já temos tudo pronto para executar nossa aplicação, vamos criar uma página web que irá alimentar os dados (neste caso, irei fazer isso diretamente no código, sem interface com o usuário). O legal do Code First é que até agora nós não fizemos nada com relação a banco de dados e mapeamento com EDMX, mas, já está tudo pronto para funcionar 🙂

Segue abaixo na Listagem 4 o código da página WebForm1.aspx:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyCodeFirst
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        AutomoveisContext automoveisDB = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            automoveisDB = new AutomoveisContext();

            if (!IsPostBack)
            {
                this.criarBanco();
                this.registraMarcas();
                this.registraModelos();
                this.registraCarros();
            }
        }
        private void registraMarcas()
        {
            automoveisDB.Marcas.Add(new Marca() { Nome = "Chevrolet" });
            automoveisDB.Marcas.Add(new Marca() { Nome = "Honda" });
            automoveisDB.Marcas.Add(new Marca() { Nome = "Fiat" });
            automoveisDB.Marcas.Add(new Marca() { Nome = "Renault" });
            automoveisDB.SaveChanges();
        }

        private void registraModelos()
        {
            //Para Chevrolet
            Marca marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Chevrolet"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Camaro" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Agile" });
            //Para Honda
            marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Honda"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Fit" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Civiv" });
            //Para Honda
            marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Fiat"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "500" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Punto" });
            //Para Renault
            marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Renault"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Clio" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Sandero" });
            automoveisDB.SaveChanges();
        }

        private void registraCarros()
        {
            //Camaro
            Modelo modelo = automoveisDB.Modelos.Single(c => c.Nome.Equals("Camaro"));
            automoveisDB.Carros.Add(new Carro()
                {
                    AnoFabricacao = 2011,
                    AnoModelo = 2011,
                    Cor = "Preto",
                    Modelo = modelo,
                });

            //Fit
            modelo = automoveisDB.Modelos.Single(c => c.Nome.Equals("Fit"));
            automoveisDB.Carros.Add(new Carro()
            {
                AnoFabricacao = 2010,
                AnoModelo = 2010,
                Cor = "Prata",
                Modelo = modelo,
            });

            //Sandero
            modelo = automoveisDB.Modelos.Single(c => c.Nome.Equals("Fit"));
            automoveisDB.Carros.Add(new Carro()
            {
                AnoFabricacao = 2010,
                AnoModelo = 2011,
                Cor = "Verde",
                Modelo = modelo,
            });
            automoveisDB.SaveChanges();
        }

        /// <summary>
        /// Método responsável por verificar se o banco de dados já existe
        /// se Sim = Deletar banco e Criá-lo novamente
        /// se Não, Criar banco
        /// </summary>
        private void criarBanco()
        {
            //Verifica
            if (automoveisDB.Database.Exists())
                automoveisDB.Database.Delete();
            automoveisDB.Database.Create();
        }
    }
}

Vejam que o código acima é simples e segue um pequeno fluxo:

1. Ele irá verificar se o banco de dados já está registrado no servidor informado. Caso sim, o code first irá deletar o banco e criá-lo novamente. Essa ação,  claro é bem prática para ambiente de desenvolvimento.
também é possivel utilizar o método CreateIfNotExists(); que como o próprio nome diz, ele somente irá criar o banco de dados caso ele não exista. Ambos os métodos retornam booleano informando se foi ou não possivel criar o banco.

2. Registra as marcas

3. Registra os modelos

4. Registra os carros

Depois da execução da página, é possivel observar no servidor de BD a criação do banco com o nome de AutomoveisDB e 4 tabelas. três delas nós que criamos e a outra (EdmMetadata) é uma tabela default do Code First responsável por armazenar um Hash do modelo existente. Esse Hash é utilizado para verificar se o modelo atual ainda é válido para banco criado, ou seja, se for criado um campo novo em alguma entidade, ou até mesmo uma nova entidade, os hashs não coincidirão e a utilização não será possivel.

Bom, espero que tenha dado pra entender um pouco do Code First, essa nova funcionalidade do Entity Framework que veio pra ajudar e muito os desenvolvedores.

Até a próxima

Anúncios
Esse post foi publicado em C#, Code First, Entity Framework, LINQ. Bookmark o link permanente.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s