Archive for the ‘Entity Framework’ Category.

Entity Framework PowerTool no Visual Studio 2015

Olá,

Se você usa bastante o EF CodeFirst como eu e já está no Visual Studio 2015, deve ter sentido falta do EF PowerTools. Infelizmente ele ainda não foi portado para esta versão do Visual Studio.

Mas calma aí, existe uma maneira de instalar a versão atual no VS 2015. Para isto, primeiro baixe o componente da Visual Studio Galery. Veja na imagem abaixo que ele não suporta o VS 2015:

image

Agora vem o truque…

Não sei se vocês sabem, mas o aqrquivo VSIX é na verdade um arquivo ZIP, então vamos renomear o arquivo baixado para .ZIP e depois vamos extair o conteúdo no mesmo diretório, ficando assim:

image

Agora vamos abrir o aqrquivo “extension.vsixmanifest”, pois é nele que estão as versões suportadas do Visual Studio. Com o arquivo aberto vamos adicionar as linhas, logo abaixo do bloco da versão 12.0:

<VisualStudio Version="14.0">
     <Edition>Pro</Edition>
</VisualStudio>

Altere o arquivo e salve-o, ele vai ficar assim:

image

Agora só precisamos compactar tudo novamente. Vamos fazer isto colocando o nome de EFPowerToolsVS2015.zip. Não se esqueca de apagar o arquivo original antes (o que renomeamos para ZIP). Agora teremos a seguinte lista de arquivos:

image

Para finalizar renomeie o arquivo .ZIP para .VSIX e clique para instalar!

Pronto, agora você tem o Entity Framework PowerTools funcionando no seu Visual Studio 2015!

Se você não quiser realizar os passos acima, cliquei aqui e baixe o arquivo VSIX pronto!

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

EntityFramework-Lendo seu banco de dados com o Visual Studio 2013 Update 2

Olá pessoal,

Há algum tempo atrás eu fiz um post falando sobre como aproveitar seu banco de dados existente com o EntityFramework PowerTools, mas o modelo do PowerTools não permite escolher as tabelas ou views que você quer ler, e ás vezes isto é bem útil.

Com o lançamento do Update 2 do Visual Studio 2013 e também do EntityFramework 6.1, foi adicionada uma nova opção nas fontes de dados, que agora permite também fazer engenharia reversa com CodeFirst escolhendo quais tabelas e views serão lidas, a exemplo do que já era possível com o EntityFramework Designer.

Para demonstrar isto, vamos criar um novo projeto do tipo Console no Visual Studio 2013:

SNAGHTMLa64a79f

Agora vamos fazer a engenharia reversa, mas utilizando o novo recurso do Visual Studio 2013. Para isto, no seu projeto clique com o botão direito do mouse na solution e depois vá em Add/New Item:

image

Agora vamos adicionar um ADO.NET Entity Data Mode:

SNAGHTMLa676ebe

E veja que agora existe uma nova opção chamada “Code First from database” e com ela iremos ler um banco de dados já existente e criar todo o código para o CodeFirst.

SNAGHTMLa69ebd4

Vamos então escolher esta opção e colocar a conexão para o nosso banco de dados existente: (no meu exemplo estou usando o banco da Microsoft chamado Northwind)

SNAGHTMLa69538c

Agora você pode escolher as tabelas e views que quiser para o seu projeto do CodeFirst:

SNAGHTMLa6b3694

Feito isto, todas as classe serão geradas no CodeFirst, mas com uma grande diferença em relação ao PowerTools: as informações de mapeamento são geradas como DataAnnotations ao invés de FluentApi. Veja o exemplo da classe Products:

   1: public partial class Products

   2:     {

   3:         [Key]

   4:         public int ProductID { get; set; }

   5:

   6:         [Required]

   7:         [StringLength(40)]

   8:         public string ProductName { get; set; }

   9:

  10:         public int? SupplierID { get; set; }

  11:

  12:         public int? CategoryID { get; set; }

  13:

  14:         [StringLength(20)]

  15:         public string QuantityPerUnit { get; set; }

  16:

  17:         [Column(TypeName = "money")]

  18:         public decimal? UnitPrice { get; set; }

  19:

  20:         public short? UnitsInStock { get; set; }

  21:

  22:         public short? UnitsOnOrder { get; set; }

  23:

  24:         public short? ReorderLevel { get; set; }

  25:

  26:         public bool Discontinued { get; set; }

  27:

  28:         public virtual Categories Categories { get; set; }

  29:     }

Veja que a classe foi gerada e o DataAnnotations foi criado.

Agora é só utilizar o EntityFramework CodeFirst!

Abraços e até a próxima,

Carlos dos Santos.

Criando Índices no Entity Framework CodeFirst

Olá pessoal,

A partir da versão 6.1 do EntityFramework é possível criar índices no banco de dados, especificando isto diretamente nas classes no código fonte. Esta criação dos índices é feira através do atributo Index diretamente sobre o campo da classe. Mas atenção: isto só é possível utilizando o recurso Migrations do EntityFramework.

Para demonstrar este recurso, vamos criar um projeto do tipo Console no Visual Studio e vamos adicionar o EntityFramework CodeFirst usando o pacote NuGet.

Criando o Projeto Console:

 SNAGHTML4fb2cd3

Adicionando o EntityFramework CodeFirst com o NuGet Package (Tools/Nuget Package Manager/Package Manager Console) e iremos adicionar o pacote com o comando abaixo:

PM> Install-Package EntityFramework

Vamos agora adicionar a nossa classe de Contexto:

   1: public class Contexto : DbContext

   2: {

   3:     public DbSet<Cliente> Cliente { get; set; }

   4: }


E na sequência a classe Cliente:

   1: public class Cliente

   2:     {

   3:         public int ID { get; set; }

   4:         public string Nome { get; set; }

   5:         public string Cidade { get; set; }

   6:         public string UF { get; set; }

   7:     }

 

Criando os índices:

Vamos imaginar que você precise criar um índice para o campo Nome classe Cliente. Iremos usar então o atributo Index e também o MaxLength para determinarmos o tamanho máximo do campo. O atributo Index está no NameSpace: System.ComponentModel.DataAnnotations.Schema

   1: public class Cliente

   2:     {

   3:         public int ID { get; set; }

   4:         [Index]

   4:         [MaxLength(100)]

   5:         public string Nome { get; set; }

   6:         public string Cidade { get; set; }

   7:         public string UF { get; set; }

   8:     }

 

Veja que é bem simples, basta adicionar o atributo Index em cima do campo que você quer o índice! Você pode também dar um nome para o índice e, caso seja um índice composto (mais de um campo) indicar qual a posição do campo no índice.

Para nomear o índice, basta informar, por exemplo: [Index(“MeuIndice”)] e se você quiser informar também a posição, basta adicionar logo após o nome. Você ainda pode indicar se o índice é Clustered ou Unique. O nome do índice não é obrigatório.

Lembrando o que falei no início do post, a criação do índice é feita usando o Migrations e agora vamos adicioná-lo ao nosso projeto utilizando a Package Manager Console novamente:

PM> Enable-Migrations

Agora já podemos começar a enviar os comandos do migrations para criar ou atualizar nosso banco de dados. Começamos então adicionando um checkpoint para o migrations:

PM> Add-Migration CriacaoBanco

Se você verificar o código gerado pelo Migrations, verá a criação do índice (neste exemplo eu dei o nome “MeuIndice” para o índice):

   1: public partial class CriacaoBanco : DbMigration

   2:     {

   3:         public override void Up()

   4:         {

   5:             CreateTable(

   6:                 "dbo.Clientes",

   7:                 c => new

   8:                     {

   9:                         ID = c.Int(nullable: false, identity: true),

  10:                         Nome = c.String(maxLength: 100),

  11:                         Cidade = c.String(),

  12:                         UF = c.String(),

  13:                     })

  14:                 .PrimaryKey(t => t.ID)

  15:                 .Index(t => t.Nome, name: "MeuIndice");

  16:             

  17:         }

  18:         

  19:         public override void Down()

  20:         {

  21:             DropIndex("dbo.Clientes", "MeuIndice");

  22:             DropTable("dbo.Clientes");

  23:         }

  24:     }

 

Veja o comando .Index(t => t.nome, name: “Meu_Indice”). Ele é quem irá criar o índice quando aplicarmos a alteração no banco de dados, mas antes de criarmos o banco de dados não podemos esquecer da string de conexão de deve estar no app.config ou web.config (no caso de aplicações web). Vamos adicionar a linha com a conexão:

   1:  

   2:   <connectionStrings>

   3:     <add name="Contexto" 

   4:          connectionString="data source=(local); initial catalog=EFIndice; user id=teste; password=teste" 

   5:          providerName="System.Data.SqlClient"/>

   6:   </connectionStrings>

   7:   

   8:   

 

Agora vamos criar o banco de dados com o índice executando o comando Update-Database:

PM> Update-DataBase

Pronto, nosso banco foi criado com o índice que determinamos. Vejam a tela do Management Studio:

image

Ao invés de criar o banco diretamente, você também pode adicionar o parametro –Script ao Update-Database para assim, gerar o script do seu bando de dados.

Agora você já pode adicionar a criação de índices ao seus projetos do EntityFramework e assim, melhorar a performance de suas consultas.

Abraços e até a próxima,

Carlos dos Santos.

Visual Studio Summit 2014

Pessoal,

No último sábado (26/04/2014) aconteceu em São Paulo, na sede da Microsoft, mais uma edição do Visual Studio Summit. Neste ano tive a grata satisfação de realizar 5 palestras, ufa! Foi uma maratona!

Fiz na verdade 5 palestras sobre dois Temas: Novidades do Visual Studio 2013 e Entity Framework Framework 6, a maioria com lotação máxima das salas.

Gostaria de agradecer ao Ramon novamente pela oportunidade e a todos que participaram das palestras e principalmente pelas interações durante as palestras.

Vejam as fotos do evento aqui e das minhas palestras aqui.

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

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.

DevChamps-EntityFramework6

Pessoal,

Acabei de fazer uma apresentação sobre Entity Framework 6 e uma breve introdução ao uso de EF com MVC e WebAPI para grupo DevChamps da Microsoft. Este é grupo seleto com grandes empresas do mercado e me sinto muito honrado e feliz por ter esta oportunidade!

Nesta apresentação falei de algumas novidades do Entity Framework 6, e mostrei como utilizar o Scaffold em aplicações MVC e webAPI para integração com o EF. Os feedbacks foram muito legais e positivos!

Agradeço a Microsoft pela confiança e espero estar em breve participando novamente!

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.

Melhorando o tempo de carga do Entity Framework com NGEN

A partir do Entity Framework 6, todos os componentes do EF estão dentro da DLL EntityFramework.dll e não mais divididas entre vários componentes do .Net Framework. Sendo assim, a DLL do EF não está otimizada para o JIT (Just in Time) do computador onde está sendo rodado, assim como o .Net está.

Nós podemos melhorar isto executando o comando Ngen.exe, que pré-compila a DLL e elimina este processo durante a carga da DLL. Assim o tempo de carga fica menor e podemos ganhar alguns segundos na carga da nossa aplicação.

Para fazer isto, abra um prompt de comandos do Visual Studio Studio, ele fica dentro das opções de instalação do Visual Studio, com um nome parecido com este: “Developer Command Prompt for VS 20xx”. No meu caso estou usando o VS 2013, então o prompt está como “Developer Command Prompt for VS2013”.

Abra este prompt como administrador, vá até o diretório da sua aplicação e execute o comando NGen, como abaixo:

C:Meu Projeto>ngen install EntityFramework.dll

Após isto você verá uma tela parecida como esta:

image

Valeu pessoal e até a próxima,
Carlos dos Santos.

Entity Framework 6–Gerando Log dos comandos SQL

Olá,

O Entity Framework 6 RC já foi lançado! Agora é a hora de começar a trabalhar na migraçãoda versão 5 para a 6 e ver as novas funcionalidades. As especificações sobre as novas funcionalidades podem ser encontradas aqui.

Dentre as muitas novidades, que vamos explorar nos post seguintes, hoje vou destacar uma que acho bem interessante: o log dos comandos enviados ao banco de dados.

Um ORM (Object-Relational Mapping), ou simplesmente um Mapeamento Objeto-Relacional traduz comandos de uma linguagem de programação, no nosso caso C# e LINQ, para comandos de banco de dados. A eficiência do ORM está diretamente relacionada a como os comandos para o banco de dados são gerados, ou seja, pegar os comandos escritos em C# e convertê-los em comandos SQL.

Na versão 6 do Entity Framework foi introduzido um novo objeto que nos permite interceptar os comandos que estão sendo enviados para o banco de dados e assim podemos ver o que acontece “por baixo dos panos”. Isto também podem ser feito colocando uma ferramenta de profiler de banco de dados. No caso do Microsoft SQL Server esta ferramenta é o SQL Server Profiler, mas existem vários outros.

No caso do nosso exemplo, vamos executar um método para cada operação em LINQ que será executada no Entity Framework, e para iniciarmos o nosso exemplo, vamos criar um projeto do tipo Console Application usando o .Net 4.5 (o uso do .Net 4.5 é importante para suportar todas as funcionalidades do Entity Framework 6).

Criando um novo projeto do tipo Console Application:

SNAGHTML476eb602

Criado o nosso projeto, vamos adicionar o Entity Framework através da janela do  Nuget, que está em Tools/Library Packager Manager/Packager Manger Console e dentro dele iremos executar o comando abaixo:

PM> Install-Package EntityFramework –Pre

Veja que a opção “-Pre” é quem irá instalar o Entity Framework 6 RC, visto que ele ainda não foi liberado oficialmente e ainda é um release candidate.

Agora vamos criar um contexto bem simples com uma classe Cliente. Para isto adicione uma nova classe e chame-a de Contexto, como no exemplo abaixo:

   1: public class Contexto : DbContext

   2: {

   3:     public DbSet<Cliente> Cliente {get; set;}

   4:  

   5: }

Agora vamos adicionar a classe Cliente:

   1: public class Cliente

   2:     {

   3:         public int ID { get; set; }

   4:         public string Nome { get; set; }

   5:     }

E por fim vamos modificar o arquivo App.Config para direcionarmos o local e o nome do banco de dados a ser criado: (isto é somente um exemplo e o seu arquivo poderá ficar diferente)

   1: <?xml version="1.0" encoding="utf-8"?>

   2: <configuration>

   3:   <connectionStrings>

   4:     <add name="Contexto" connectionString="data source=(local); initial catalog=EFLog; integrated security=true;" providerName="System.Data.SqlClient"/>

   5:   </connectionStrings>

   6: </configuration>

Agora vamos ao que interessa, ou seja, vamos adicionar o LOG do SQL. Para isto, no Program.cs vamos inserir os seguintes comandos:

   1: class Program

   2:     {

   3:         static void Main(string[] args)

   4:         {

   5:             var db = new Contexto();

   6:             db.Database.Log = GravaLog;

   7:  

   8:             var cli = new Cliente() { Nome = "Carlos" };

   9:             db.Cliente.Add(cli);

  10:             db.SaveChanges();

  11:  

  12:             var consulta = from c in db.Cliente

  13:                            select c;

  14:             foreach(var c in consulta)

  15:             {

  16:                 Console.WriteLine(c.Nome);

  17:             }

  18:         }

  19:  

  20:         public static void GravaLog(string sql)

  21:         {

  22:             Console.WriteLine("Comando SQL: "+sql);

  23:         }

  24:     }

O método GravaLog() é atrbuído a propriedade Log do DataBase do Contexto, sendo assim, todos os comandos enviados para o banco de dados são também enviados para este método e dentro dele simplesmente chamamos o método Console.WriteLine() para mostrar os comandos na tela.

Ao executar o programa, você verá algo como a imagem abaixo:

SNAGHTML47817c48

Esta é uma implementação bastante simples da implementação do Log de comandos disponível agora na versão 6, mas com certeza você poderá utilizar de uma maneira bem mais elaborada em seus projetos.

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