Posts tagged ‘msdn;c#;ef codefirst; ef’

EntityFramework–Apoveitando seu Banco de Dados com PowerTools

Olá pessoal,

Quando uma empresa resolve adotar uma ferramenta de ORM (Mapeamento Objeto Relacional – no nosso caso o EntityFramework),  começa uma grande quebra de paradigma, pois você vai deixar de acessar o banco de dados diretamente (Select, Insert, Update, Delete, etc) e vai passar a trabalhar somente com classes e objetos. Isto torna o desenvolvimento muito mais fácil e produtivo, uma vez que você não precisa ficar se preocupando com os comandos que vão para o banco de dados, já que isto é trabalho do ORM.

Mas e quando você já tem um banco de dados pronto ? Isto sempre gera outra discussão, afinal você pode construir um novo banco, aproveitar o processo e melhorar tudo ou reaproveitar a estrutura do banco existente e incluir somente o ORM ? Quer ouvir outra coisa muito comum: você está criando uma nova funcionalidade ou novo projeto, e resolve utilizar o EntityFramework, mas precisa ler e gravar dados do banco atual. Como fazer ? Escrever as classes POCO na mão ? Obviamente que não, pois para isto existem diversas ferramentas que podem fazer isto para você e uma delas que vamos apresentar hoje é o EntityFramework PowerTools.

Para iniciarmos você precisa baixar o PowerTools através do gerenciamento de extensões do Visual Studio (Tools/Extensions and Updates), e depois procurar pelo Entity Framework Power Tools, conforme a figura abaixo:

SNAGHTML4333684

No meu caso já está instalado, mas caso o seu ainda não esteja, clique no botão “Install” e pronto! Agora vamos criar um projeto para explorar os recursos.

Vamos iniciar criando um projeto Console e adicionando o EntityFramework através do NuGet:

SNAGHTML434d0ea

Agora vamos adicionar o EF:

image

Agora que já temos o EntityFramework, vamos verificar no menu da nossa Solution um novo item chamado Entity Framework (para ver este menu, clique com o botão direito sobre o nome do seu projeto):

image

Veja que temos duas opções:

  • Reverse Engineer Code First: permite ler um banco de dados existente e gerar as classes e o contexto;
  • Customize Reverse Engineer Templates: permite mudar o formado de geração das classes através de um arquivo T4

Se você escolher customizar os templates, terá os seguintes arquivos adicionados ao projeto, que poderão ser modificados de acordo com sua necessidade:

image

Escolhendo gerar as classes com a opção “Reverse Engineer Code First” você terá uma tela para colocar os dados de acesso ao seu banco de dados, faça isto e depois clique em OK para iniciar a geração das classes:

SNAGHTML43ed31c

Agora já temos todo o banco de dados mapeado, e na versão atual do Entity Framework, isto inclui as tabelas e as views. Veja uma parte destas classes na nossa solution:

image

A engenharia reversa faz todo o mapeamento de atributos utilizando FluentAPI e a pasta “Mapping” contém estes mapeamentos.

Agora vamos clicar com o botão direito do mouse em cima do nosso contexto: NorthwindContext.cs:

image

Veja que agora temos outras opções, que são relativas ao banco que foi mapeado. Como estamos trabalhando com CodeFirst, não temos um diagrama visual do nosso banco de dados, mas com a ajuda do PowerTools, clicando na primeira opção: “View Entity Data Model (Read-only), você pode visualizar graficamente como está seu banco de dados, veja abaixo:

image

Veja que todos os relacionamentos foram criados e estão gerados através do FluentAPI no arquivo de mapeamento. Repare que no menu está escrito “Read-only” e isto quer dizer que este diagrama serve apenas para leitura, então não adianta escrever nada nele que não será refletido nas entidades.

É possível também gerarmos um arquivo XML, que se assemelha ao arquivo EDMX (Model First e DataBase First). Existe também uma opção para gerarmos um script DDL, que pode ser executado no servidor de banco de dados para a criação do mesmo. No caso do EntityFramework CodeFirst existe o Migrations que elimina este trabalho de criação e atualização do banco de dados. Veja este post aqui.

Por fim temos uma opção bem interessante: “Generate Views” que gera consultas optimizadas para o banco de dados e ajuda a melhorar a performance da nossa aplicação. Lembrando que se você optar por utilizar as Views, deverá gerá-las sempre que modificar suas classes.

Espero ter esclarecido o uso da ferramenta Entity Framework PowerTools e que este artigo seja muito útil para você!

Um grande abraço e até a próxima.
Carlos dos Santos.

Melhorando a performance do Entity Framework com NGen

Olá pessoal,

Em um outro post eu falei bem rapidamente sobre o NGen, que serve para pré-compilar os assemblies de um aplicação, fazendo antecipadamente o trabalho do JIT (Just in Time Compiler).

Só para relembrar um pouco, a figura abaixo mostra o processo de execução de uma aplicação em .Net:

image

Em um processo natural de desenvolvimento em .Net, o que acontece é basicamente o que está na figura acima, ou seja, você escreve seu código, compila e depois executa. Mas na execução entra em ação o JIT, que pega o código gerado (Assembly) e traduz para código nativo, ou linguagem de máquina, que então será executado pelo processador.

Durante a instalação do .Net Framework em um computador, este processo é executado para todos os componmentes do .Net, ou seja, o núcleo doi .Net é automaticamente pré-compilado em seu computador, mas todo o código que você produz não passa por este processo.

Como eu já falei no post anterior, desde a versão 6 o Entity Framework funciona separado do .Net, através da EntityFramework.Dll, que normalmente é baixada pelo NuGet dentro do Visual Studio. Este processo simplesmente baixa a DLL do repositório do NuGet e copia para uma pasta do seu projeto. Isto é ótimo e funciona muito bem!

Muitas pessoas reclamam em fóruns e blogs sobre o tempo de carga inicial do Entity Framework, ou seja, o primeiro comando executado, seja ela qual for, demora um pouco, mas todas as instruções subsequentes são muito rápidas. Logicamente que o desenho do modelo e o comando podem influenciar neste tempo, mas uma coisa que influencia muito é a falta da pré-compilação.

Vamos ver um exemplo bem simples. Vou criar um projeto Console em C# e fazer engenharia reversa usando o Entity Framework PowerTools, que já expliquei em alguns posts anteriores. Então para me acompanhar, crie um projeto do tipo Console no Visual Studio, conforme a figura abaixo:

SNAGHTML4098cce

Agora vamos fazer engenharia reversa no banco de dados Northwind, mas você pode utilizar qualquer outro banco de dados que tenha. PS: não esqueça de instalar o EntityFramework usando NuGet: Install-Package EntityFramework.

image

Agora vou escolher o banco de dados e gerar as classes.

Para mostrar a diferença de performance, vou criar uma simples consulta no EF e para marcar o tempo utilizaremos a classe StopWatch(). Veja abaixo:

   1:  static void Main(string[] args)
   2:          {
   3:              Stopwatch contador = new Stopwatch();
   4:   
   5:              contador.Start();
   6:   
   7:              var db = new NorthwindContext();
   8:   
   9:              var dados = db.Customers;
  10:   
  11:              foreach(var c in dados)
  12:              {
  13:                  Console.WriteLine(c.CompanyName);
  14:              }
  15:              contador.Stop();
  16:              Console.WriteLine("\n\nTempo da consulta: {0} segs.\n\n",contador.Elapsed.TotalSeconds);
  17:          }

 

Veja o resuiltado:

image

Agora vamos utilizar o NGen neste projeto e refazer o teste. Para isto abra um prompt de comando do Visual Studio (como administrador) e execute o comando abaixo:

ngen Install EFPerformance.exe

Você ver algo assim:

image

Repare que além do nosso projeto (EFPerformance.exe) a dll do EntityFramework também foi compilada.

Agora vamos executar o programa novamente, direto da linha de comandos e olhem a diferença de velocidade:

image

Perceba que ficou extremamente mais rápido!!!

Agora se você tem uma aplicação web, você pode melhorar a performance usando comando é aspnet_compiler, mas ele não gera imagens nativas como o NGen, apesar de incrementar a performance através da pré-compilação de alguns arquivos do projeto (.aspx, .ascx, app_code, etc). Se preferir, a IDE do Visual Studio tem esta opção na publicação da aplicação web:

SNAGHTML41af2f8

Espero que tenham gostado das dicas!

Abraços e até a próxima.

Carlos dos Santos.

Entity Framework–CodeBase Configuration (Interception)

Olá pessoal,

Uma das novidades do Entity Framework 6 é a possibilidade de fazermos as configurações do nosso modelo usando código ao invés dos tradicionais arquivos de configuração (app.config/web.config). Além disto, temos agora muitas outras configurações que podem ser modificadas através da classe DbConfiguration.

Dentre as várias opções de configuração que temos através do DbConfiguration, existe uma chamada Interception (veja mais aqui), onde podemos interceptar várias operaçoes que são enviadas ao banco de dados pelo Entity Framework. Neste exemplo iremos interceptar o envio de comandos para o banco de dados e gerar um arquivo texto de log.

Criando o projeto de exemplo:

Para começar, vamos criar um projeto do tipo Console usando o Visual Studio 2013 e em seguida iremos adicionar o Entity Framework através do NuGet:

image

Adicionando o Entity Framework Code First:

Após criado o projeto, vamos adicionar o Entity Framework através do NuGet. Para isto abra o menu Tools/Library Package Manager/Package Manager Console e depois digite o comando abaixo:

PM> Install-Package EntityFramework

Neste exemplo estou utilizando também o Entity Framework PowerTools,  pois vamos fazer uma engenharia reversa do banco de dados NorthWind, que é disponibilizado pela Microsoft aqui. O recurso de engenharia reversa permite que possamos pegar um banco de dados existente e gerar as classes para o Entity Framework a partir dele.

Para fazer a engenharia reversa, clique com o botão direito do mouse em cima do nome da sua solution e no menu de contexto escolha: Entity Framework/Reverse Engineer Code First, conforme a figura abaixo:

image

Este comando irá abrir uma janela solicitando as informações do banco de dados. Complete com as suas informações, no meu caso a tela é a seguinte:

SNAGHTML5372fbd

Iniciando a implementação do Interception

Agora que já temos o banco de dados mapeado, vamos implementar a classe de configuração. Adicione ao projeto uma nova classe chamada Configuracao.cs e vamos colocar o código abaixo:

   1: public class Configuracao : DbConfiguration

   2:     {

   3:         public Configuracao()

   4:         {

   5:             

   6:         }

   7:     }

Esta é a classe base para a configuração. Nenhum código é necessário para chamar esta classe, pois o Entity Framework irá identificá-la desde que esteja no mesmo Assembly da aplicação, ou seja, você não precisa chamar esta classe diretamente em nenhuma parte do seu código.

Como vamos interceptar os comandos enviados para o banco de dados e iremos gerar um log, vamos implementar a nossa classe que irá gerar os logs. Para isto vamos criar uma outra classe chamada InterceptaSQL, veja o código abaixo:

   1: public class InterceptaSQL: IDbCommandInterceptor

   2:     {

   3:  

   4:         private string arquivoLog;

   5:         public InterceptaSQL()

   6:         {

   7:             string caminho = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);

   8:             arquivoLog = Path.Combine(caminho, "Log.txt");

   9:         }

  10:  

  11:         private void EscreveLog(string s)

  12:         {

  13:             StreamWriter log = File.AppendText(arquivoLog);

  14:             log.WriteLine(string.Format("{0} - {1}n", DateTime.Now.ToString(), s));

  15:             log.Close();

  16:         }

  17:         public void NonQueryExecuting(

  18:             DbCommand command, DbCommandInterceptionContext<int> interceptionContext)

  19:         {

  20:             GravaLog("Executando SQL",command, interceptionContext);

  21:         }

  22:  

  23:         public void NonQueryExecuted(

  24:             DbCommand command, DbCommandInterceptionContext<int> interceptionContext)

  25:         {

  26:             GravaLog("SQL executado",command, interceptionContext);

  27:         }

  28:  

  29:         public void ReaderExecuting(

  30:             DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)

  31:         {

  32:             GravaLog("Executando Reader",command, interceptionContext);

  33:         }

  34:  

  35:         public void ReaderExecuted(

  36:             DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)

  37:         {

  38:             GravaLog("Reader executado",command, interceptionContext);

  39:         }

  40:  

  41:         public void ScalarExecuting(

  42:             DbCommand command, DbCommandInterceptionContext<object> interceptionContext)

  43:         {

  44:             GravaLog("SQL Scalar executando",command, interceptionContext);

  45:         }

  46:  

  47:         public void ScalarExecuted(

  48:             DbCommand command, DbCommandInterceptionContext<object> interceptionContext)

  49:         {

  50:             GravaLog("SQL Scalar executado",command, interceptionContext);

  51:         }

  52:  

  53:         private void GravaLog<TResult>(string TipoComando,

  54:             DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)

  55:         {

  56:             if (interceptionContext.Exception != null)

  57:             {

  58:                 EscreveLog(string.Format("ERRO - Comando SQL: {0},  falhou com exceção: {1}",

  59:                     command.CommandText, interceptionContext.Exception));

  60:             }

  61:             else

  62:             {

  63:                 EscreveLog(string.Format("{0}: {1}",TipoComando, command.CommandText));

  64:             }

  65:         }

  66:     }

Nesta classe estamos implementando todos os métodos da interface IDbCommandInterceptor, e também o nosso método para a geração do arquivo texto com o log (linhas 11 a 16). Neste exemplo eu escolhi gravar o arquivo de log no mesmo diretório da aplicação e para isto eu peguei o diretório dentro do assembly usando reflection (linha 7). A gravação do log é bem simples e armazenamos a data/hora, o tipo da operação e o comando executado. Você pode modificar o método GravaLog() e tratar qualquer outra informação que achar necessária.

Ativando a Interceptação

Agora que já implementamos a nossa classe para interceptar os comandos, precisamos informar ao Entity Framework da existência desta classe. Para isto vamos voltar a nossa classe Configuracao.cs e adicionar o código abaixo ao construtor:

   1: public class Configuracao : DbConfiguration

   2:     {

   3:         public Configuracao()

   4:         {

   5:             this.AddInterceptor(new InterceptaSQL());

   6:         }

   7:     }

O método AddInterceptor() informa ao Entity Framework que iremos interceptar as operações descritadas na classe InterceptaSQL.

Testando a implementação

Para testamos a nossa classe, vamos executar algumas operações no Entity Framework. Veja abaixo o código que utilizamos em Program.cs:

   1: static void Main(string[] args)

   2:         {

   3:             var db = new NorthwindContext();

   4:  

   5:             foreach(var p in db.Products)

   6:             {

   7:                 Console.WriteLine(p.Category.CategoryName+", "+p.ProductName);

   8:             }

   9:  

  10:             var altera = db.Products.Where(p => p.ProductID == 1).FirstOrDefault();

  11:             if(altera != null)

  12:             {

  13:                 altera.UnitPrice = 10;

  14:                 db.SaveChanges();

  15:             }

  16:         }

Ao executarmos o programa o seguinte arquivo Log.txt é gerado (apenas uma parte do arquivo foi colada aqui):

   1: 29/12/2013 23:51:38 - Executando Reader: select serverproperty('EngineEdition')

   2:  

   3: 29/12/2013 23:51:38 - Reader executado: select serverproperty('EngineEdition')

   4:  

   5: 29/12/2013 23:51:39 - Executando Reader: SELECT 

   6:     [Extent1].[ProductID] AS [ProductID], 

   7:     [Extent1].[ProductName] AS [ProductName], 

   8:     [Extent1].[SupplierID] AS [SupplierID], 

   9:     [Extent1].[CategoryID] AS [CategoryID], 

  10:     [Extent1].[QuantityPerUnit] AS [QuantityPerUnit], 

  11:     [Extent1].[UnitPrice] AS [UnitPrice], 

  12:     [Extent1].[UnitsInStock] AS [UnitsInStock], 

  13:     [Extent1].[UnitsOnOrder] AS [UnitsOnOrder], 

  14:     [Extent1].[ReorderLevel] AS [ReorderLevel], 

  15:     [Extent1].[Discontinued] AS [Discontinued]

  16:     FROM [dbo].[Products] AS [Extent1]

  17:  

  18: 29/12/2013 23:51:39 - Reader executado: SELECT 

  19:     [Extent1].[ProductID] AS [ProductID], 

  20:     [Extent1].[ProductName] AS [ProductName], 

  21:     [Extent1].[SupplierID] AS [SupplierID], 

  22:     [Extent1].[CategoryID] AS [CategoryID], 

  23:     [Extent1].[QuantityPerUnit] AS [QuantityPerUnit], 

  24:     [Extent1].[UnitPrice] AS [UnitPrice], 

  25:     [Extent1].[UnitsInStock] AS [UnitsInStock], 

  26:     [Extent1].[UnitsOnOrder] AS [UnitsOnOrder], 

  27:     [Extent1].[ReorderLevel] AS [ReorderLevel], 

  28:     [Extent1].[Discontinued] AS [Discontinued]

  29:     FROM [dbo].[Products] AS [Extent1]

Conclusão

O novo recurso de interceptação de comandos do Entity Framework pode ser bastante útil para você fazer depurações e análises dos comandos enviados ao banco de dados, inclusive testes de performance, já que gravamos a data/hora do início da execução e também do final.

Logicamente que este é um log bem mais aprofundado do que eu já mostrei neste outro post, mas a idéia principal é você entender o novo mecanismo de configuração do Entity Framework, que abre muitas possibilidades, incluindo a que acabamos de explorar.

Baixe o código fonte do exemplo.

Um grande abraço e até a próxima,

Carlos dos Santos.

Visual Studio Summit 2013

Pessoal,

No último sábado, dia 25/05/2013, aconteceu na sede da Microsoft em SP o Visual Studio Summit 2013. Neste ano tive o prazer de realizar duas palestras: Entity Framework 6 e Debug de Aplicações Windows 8 no Device. As duas palestras também foram repetidas, o que tornou o meu dia um pouco mais intenso!

Gostaria de agradecer a excelente audiência que tive nas palestras, onde tive salas praticamente lotadas!

Aqui estão as fotos do eventos que publiquei no Facebook. Para quem esteve na palestra de Entity Framework, eu também disponibilizei o código fonte dos exemplos no meu Skydrive.

Vídeo da Palestra de EntityFramework 6

 

Vídeo da Palestra de Debug de Aplicações Windows 8 no Device

 

Abraços e até a próxima,
Carlos dos Santos.

Entity Framework–Open Source

Pessoal,

A Microsoft anunciou hoje que o Entity Framework terá seu código fonte Open Source e ela vai contar com a ajuda da comunidade para poder melhorá-lo.

Mesmo sendo Open Source, a Microsoft irá continuar o desevolvimento do produto, e já fala inclusive no roadmap do Entity Framework 6.

Se você tem interesse em conhecer o código fonte, e principalmente, contribuir, acesse o portal do projeto no CodePlex no link: http://entityframework.codeplex.com/

Abraços e até a próxima.
Carlos dos Santos.

EntityFramework CodeFirst

No post anterior, eu falei em como trabalhar com Entity Framework usando o Designer, ou seja, um modelo de classes criado a partir de um arquivo EDMX. Este modelo funciona perfeitamente em diversos tipos de projetos, mas o grande incoveniente é ter um arquivo EDMX para cada tipo de banco de dados do seu projeto.

Então vamos agora usar uma abordagem diferente, mas nem tão diferente assim do artigo anterior. Nossa necessidade ainda é manter o isolamento do banco de dados e trabalhar somente com objetos. O CodeFirst, como o próprio nome sugere, nos leva a criar primeiramente as classes POCO e depois o banco de dados, mas é possível também pegar um banco de dados existente e gerar o CodeFirst.

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:

SNAGHTMLa23ac4a_thumb1_thumb

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

image_thumb1_thumb

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:

image_thumb3_thumb1

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. Eu já fiz outro post falando só sobre Gerenciamento de Strings de Conexão.

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:

image_thumb5_thumb1

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

image_thumb3[1]

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:

image_thumb9_thumb1

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:

SNAGHTMLa560840_thumb1_thumb1

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.

Espero que o artigo seja útil para vocês e se assim desejarem façam seus comentários ou sugestões.

Até a próxima,
Carlos dos Santos.