Entity Framework Code First

Do Carlos dos Santos

Março 2012

Hh972463.060DE5057573180CEC6D227C6D3E2207(pt-br,MSDN.10).png

O Entity Framework faz uma ponte entre as classes POCO e o banco de dados utilizando um container que chamamos de Contexto. O contexto é o responsável por mapear as nossas classes com o banco de dados e também por informar ao engine quem é o banco de dados, através da string de conexão, e isto é o que mais me agrada no Code First, você precisa trocar somente a string de conexão para mudar de banco. Nenhum tipo de alteração no código é necessária.

Instalando o Entity Framework Code First

Antes de começarmos a escrever as classes, precisamos instalar o Entity Framework CodeFirst, que é basicamente composto pela EntityFramework.DLL. Faremos isto isando o NuGet, que é um instalador de pacotes para o Visual Studio. Se você ainda não o possui, vá até o Extension Manager do Visual Studio (Tools/Extension Manager) e instale.

Hh972463.F665C71358B9F81C285DFCBA1DD13728(pt-br,MSDN.10).png

Depois de instalado o NuGet, vá em Tools/Library Package Manager/Package Manager Console. Isto vai abrir o gerenciador do NuGet.

Hh972463.3DA07F826C4646C458BD546A5754C22A(pt-br,MSDN.10).png

Agora digite o comando: Install-Package EntityFramework dentro do console, isto irá instalara o EF CodeFirst e suas dependências.

Criando um projeto com o EntityFramework CodeFirst

Vamos criar uma classe de contexto que chamaremos de Contexto.cs, esta classe irá herdar de DbContext e nela iremos mapear nossas tabelas.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Data.Entity;
   6:  
   7: namespace EFCodeFirst
   8: {
   9:     public class Contexto : DbContext
  10:     {
  11:         public DbSet<Grupo> Grupo { get; set; }
  12:         public DbSet<Produto> Produto { get; set; }
  13:     }
  14: }

O segredo aqui é o DBSet<>, pois ele faz o mapeamento da nossa classe para o banco e vincula a um objeto, que utilizaremos para fazer as operações com o BD.

Veja o código da classe Grupo

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.ComponentModel.DataAnnotations;
   6:  
   7: namespace EFCodeFirst
   8: {
   9:     [Table("Grupo")]
  10:     public class Grupo
  11:     {
  12:         public int ID { get; set; }
  13:         [Required(ErrorMessage="Nome não pode ser branco.")]
  14:         public string Nome { get; set; }
  15:  
  16:         public virtual IQueryable<Produto> Produtos { get; set; }
  17:     }
  18: }

E da classe Produto

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.ComponentModel.DataAnnotations;
   6:  
   7: namespace EFCodeFirst
   8: {
   9:     [Table("Produto")]
  10:     public class Produto
  11:     {
  12:         public int ID { get; set; }
  13:         [Required(ErrorMessage="Nome não pode ser branco.")]
  14:         public string Descricao { get; set; }
  15:         public int GrupoID { get; set; }
  16:  
  17:         [ForeignKey("GrupoID")]
  18:         public virtual Grupo Grupo { get; set; }
  19:     }
  20: }

No CodeFirst podemos controlar todos os aspectos do mapeamento das classes com o banco de dados, desde o nome da tabela no banco, obrigatoriedade dos campos, tamanho, etc.

Na classe Grupo, eu determinei o nome da tabela no banco de dados (linha 9), ou seja, podemos ter um nome para a classes e outro para a tabela no banco de dados. Informei também que o nome não pode ser banco e vinculei uma mensagem, que pode ser usada em projetos MVC e WPF (linha 13). Finalmente criei o relacionamento entre Grupo e Produto (linha 16).

Na classe Produto, eu determinei também o nome da tabela no banco de dados, e o campo obrigatório. Fiz também o relacionamento com a tabela grupo através do campo GrupoID (linhas 15 e 17,18).

O EF identifica também automaticamente as chaves primárias das tabelas, desde que você as chame por ID ou nome_da_tabelaID, exemplo: GrupoID ou ProdutoID.

Um coisa muito legal que o EF CodeFirst faz para nós é criar o banco de dados, mas isto depende do provider do seu banco de dados, nem todos aceitam a criação do banco.

Vamos agora montar um exemplo para carregar dados no nosso banco.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: namespace EFCodeFirst
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             var db = new Contexto();
  13:  
  14:             db.Database.CreateIfNotExists();
  15:  
  16:             var g1 = new Grupo() { Nome = "Peças" };
  17:             var g2 = new Grupo() { Nome = "Serviços" };
  18:  
  19:             db.Grupo.Add(g1);
  20:             db.Grupo.Add(g2);
  21:  
  22:             var p1 = new Produto() { Descricao = "Pneu", Grupo = g1 };
  23:             var p2 = new Produto() { Descricao = "Roda", Grupo = g1 };
  24:             var p3 = new Produto() { Descricao = "Alinhamento", Grupo = g2 };
  25:             var p4 = new Produto() { Descricao = "Balanceamento", Grupo = g2 };
  26:  
  27:             db.Produto.Add(p1);
  28:             db.Produto.Add(p2);
  29:             db.Produto.Add(p3);
  30:             db.Produto.Add(p4);
  31:  
  32:             db.SaveChanges();
  33:  
  34:             var dados = from p in db.Produto
  35:                         select p;
  36:  
  37:             foreach (var linha in dados)
  38:             {
  39:                 Console.WriteLine("{0,-30} - {1}", linha.Grupo.Nome, linha.Descricao);
  40:             }
  41:  
  42:         }
  43:     }
  44: }

O código acima cria o nosso banco de dados no SQL, caso ele não exista (linha 14). Após isto eu inseri os dados em Grupo e Produto, mas percebam que eu simplesmente vinculei os objetos, sem me preocupar com as chaves primárias ou estrangeiras, pois o EF resolve isto para nós desde que seu mapeamento esteja correto.

Assim ao final do código temos o banco de dados criado e os dados inseridos. Veja como ficou o banco de dados no Management Studio.

Hh972463.ED65716E212CCBFEBDAD33AA7041F4D0(pt-br,MSDN.10).png

Veja que o nome do banco de dados é o nome da aplicação mais o nome do Contexto, mas podemos resolver isto adicionando um arquivo App.Config e informando os dados do banco, então vamos adicionar um arquivo de configuração ao nosso exemplo e colocar a seguinte linha.

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:   <connectionStrings>
   4:     <add name ="Contexto" providerName="System.Data.SqlClient" connectionString="data source=(local); initial catalog=ExemploEF; user id=teste; password=teste;"/>
   5:   </connectionStrings>
   6: </configuration>

O nome da string de conexão é o mesmo nome da nossa classe de Contexto. O providerName indica que usamos SQL Server e a string de conexão é padrão de ADO.Net, informando Servidor/Banco de Dados/Usuário.

Executando nosso código novamente o banco chamado EFExemplo será criado e preenchido com os dados.

Visualizando o modelo do CodeFirst

Mas e se você quiser ver como está ficando seu modelo se você está usando somente código ? Para isto existe o Entity Framework PowerTools que permite visualizar o modelo a partir das classes e também gerar um script para o banco de dados. Vejamos como ver o modelo visual do nosso exempo.

Após instalar o PowerTools, clique com o botão direito do mouse sobre a classe Contexto.cs no seu projeto, irá aparecer um menu de contexto EntityFramework, com várias opções.

Hh972463.C0CAAE7B88604D0287E7D5901CDAABDB(pt-br,MSDN.10).png

A primeira opção é justamente a que mostra o modelo gráfico, vamos vê-lo então:

Hh972463.69BE3783ABB141E086C6263B9EFE2F50(pt-br,MSDN.10).png

Já tenho um banco de dados e quero usar o CodeFirst

Se você já tiver um banco de dados, o EF PowerTools permite que você faça engenharia reversa e gere o contexto e as classes, para isto clique com o botão direito do mouse em sua Solution no Visual Studio e escolhar Entity Framework no menu.

Hh972463.5F35E5736C4006F246D0208F3D72E496(pt-br,MSDN.10).png

Esta opção gera todas as classes e relacionamentos do seu modelo, basta informar qual o banco de dados e o servidor na janela abaixo.

Hh972463.AC205F9FF2B5FB3208DDCCC6A69CAA02(pt-br,MSDN.10).png

Não se esquece de adicionar o EntityFramework CodeFirst com o NuGet antes de fazer a engenharia reversa.

Quando usar Designer ou CodeFirst

Esta é um pergunta bem complicada, eu diria que se você usa somente um banco de dados e precisa trabalhar com Stored Procedures é melhor usar o Designer, principalmenet porquê o CodeFirst ainda não suporta procedures nativamente.

Se você quer criar uma aplicação multibanco, de maneira mais rápida e simples através de classes POCO, então o CodeFirst é sua escolha.

Muito importante saber também que o Entity Framework Designer e o CodeFirst são independentes e podem não compartilhar alguns recursos.

| Home | Artigos Técnicos | Comunidade