Quem já ouviu falar em engenharia reversa com o Entity Framework sabe que essa é a maneira de abstrair classes em C# ou VB.NET a partir de um banco de dados existente. Isto facilita muito a vida do desenvolvedor, pois todas as entidades existentes no banco de dados são lidas e depois são geradas as devidas classes no seu projeto. Para isto, antes do Update 2 do Visual Studio, era preciso instalar a ferramenta EF Power Tools disponível na galeria do Visual Studio ou através do Nuget. Uma desvantagem do EF Power Tools é que todas as entidades e views no banco geram classes, e nem sempre queremos todos os itens e, sim, apenas alguns selecionados.
No entanto, quando foi lançado o Update 2 do Visual Studio 2013, foram adicionados novos templates para esta funcionalidade e o objetivo deste artigo é mostrar passo a passo, como ler um banco de dados existente e gerar as classes com o contexto e as telas de CRUD – claro que dentro de um projeto ASP.NET MVC 5.
Portanto, o pré-requisito para este artigo é o Update 2 do Visual Studio 2013 – se já tiver instalado os Updates 3 ou 4, melhor ainda!
Projeto ASP.NET MVC 5
Abra o VS 2013, selecione File/ New Project (Ctrl + Shift + N). Na janela aberta, selecione a linguagem Visual C#, a categoria web e nos templates, ASP.NET Web Application. O nome do projeto será ArtigoCodeFirstMVC5, conforme a figura 1.

Clique no botão OK, e na janela aberta, selecione o template MVC, conforme figura 2. Clique no botão Change Authentication e selecione No Authentication, pois não iremos usar autenticação neste projeto.

Gerar o modelo de dados
Clique no botão OK e aguarde o VS criar o projeto. O próximo passo é abstrair as classes de um banco de dados existente, portanto, no modelo do MVC temos a pasta Models para isto. Claro que se você tiver um projeto de Class Library somente para acesso a dados, deverá fazer isto nele e depois referenciá-lo no MVC 5.
Como o foco deste artigo é mostrar o Code First, farei neste mesmo projeto. Na pasta Models, clique com o botão direito e selecione Add / New Item. Nos templates, selecione Visual C# / Data / ADO.NET Entity Data Model. No nome do modelo, digite ModeloDados, conforme a figura 3. Aqui vai uma dica para quem usa o .EDMX, no Visual Studio .NET 2015, ele deixará de existir, portanto, aprenda esta técnica deste artigo.

Clique no botão Add. Note que há quatro templates: dois para Designer e dois para Code First; ambos para um banco existente (from Database) ou vazio (Empty). O “from Database” sempre será gerado a partir de um banco existente e o Empty gera uma estrutura vazia – o que muitas vezes nos auxilia na criação quando ainda não se sabe a ideal estrutura das classes para gerar o banco futuramente. Neste exemplo, selecione “Code First from database”, conforme a figura 4.

Como é um assistente, clique no botão Next para o próximo passo. Aqui você deverá informar o nome do servidor (IP, localhost, local, nome do servidor, nome do computador, (localdb/v11), enfim, o nome do servidor), e qual o banco de dados. Veja na figura 5 que selecionei o banco chamado Escola, que está no meu servidor. Nem preciso dizer que se houver login, forneça, certo?! E como é uma aplicação ASP.NET, veja que a string de conexão será armazenada no arquivo Web.Config.

Clique no botão Next e o assistente se encarrega de listar todos os objetos (tables e views). Neste exemplo do meu banco de dados, figura 6, note que selecionei duas entidades. E, como não tenho nenhuma View, nada é mostrado. Sugiro você fazer um exemplo com um banco de dados que tenha Views e verá que ao final é gerada uma classe com o mesmo nome da View.
E o que significa a entidade _MigrationHistory? Como neste banco de dados usei o fantástico Migrations, esta entidade é criada automaticamente quando usei o comando Enable-Migrations / Update-Database.

Para finalizar o assistente, clique no botão Finish e aguarde a criação das classes. Você nem precisa se preocupar, que este processo já adiciona as referências necessárias na pasta References. Abra a pasta Models e veja que foram criadas três classes, sendo: Aluno, Professor e ModeloDados.
Primeiramente, vamos analisar o ModeloDados.cs. Aqui você nota que a classe ModeloDados herda de DbContext. Só isto já vale uma economia de muitas linhas de códigos, pois tudo o que diz respeito ao banco em si, é responsabilidade do DbContext, o qual cria, exclui, verifica se existe o banco, dentre outras coisas. E, claro que para aprender mais sobre uma classe, pressione F12 sobre a classe e explore as funcionalidades.
Em seguida, no construtor da classe, nota-se que há uma referência ao “name=ModeloDados”, o qual é o nome da chave que está no bloco <ConnectionString> no arquivo Web.Config. Esta é a chave que aponta para o banco de dados em si, ou seja, que contém toda a string de conexão.
Depois são criadas as propriedades para referenciar as classes que foram abstraídas no banco, sendo Aluno e Professor. Observe que ambas são do tipo DbSet<TEntity>, onde TEntity é o nome da classe. O DbSet é a melhor coisa que inventaram, pois todo o CRUD é gerado dinamicamente no DbSet. Ou seja, todas as instruções de manipulações de dados no banco (Insert, Update, Delete e Select) são criadas em tempo de execução. Costumo brincar nas palestras que no compilador quem faz isto são os indianos.
C#
namespace ArtigoCodeFirstMVC5.Models
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
public partial class ModeloDados : DbContext
{
public ModeloDados()
: base("name=ModeloDados")
{
}
public virtual DbSet<Aluno> Aluno { get; set; }
public virtual DbSet<Professor> Professor { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
}
Veja a estrutura da classe Professor com todas as referências e uso do DataAnnotations como campo requerido (Requerid), tamanho do campo (StringLength), e ao final uma referência à propriedade Aluno que é do tipo ICollection<Aluno>. Observe que a declaração do “virtual” faz com que haja uma navegação entre as classes Professor e Aluno, ou seja, um professor tem uma coleção de alunos.
Como que estas classes são geradas? Tudo no Visual Studio é gerado a partir de um template escrito em DSL (Domain Specific Language), ou seja é um gerador de código escrito em C# ou VB.NET. Você pode escrever o seu próprio gerador (é um arquivo do tipo text template (.tt)) de códigos de acordo com a sua necessidade ou padrão da empresa.
O diretório padrão dos templates (*.tt) é o C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplates\CSharp\Data\1028\DbCtxCSEF6, mas é claro que depende da linguagem e da funcionalidade a ser criada.
C#
namespace ArtigoCodeFirstMVC5.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Professor")]
public partial class Professor
{
public Professor()
{
Aluno = new HashSet<Aluno>();
}
public int ProfessorID { get; set; }
[Required]
[StringLength(200)]
public string Nome { get; set; }
public string Telefone { get; set; }
public decimal? Salario { get; set; }
public string TwitterBlog { get; set; }
public string Materia { get; set; }
public bool Disponivel { get; set; }
public DateTime? Admissao { get; set; }
public virtual ICollection<Aluno> Aluno { get; set; }
}
}
Veja a estrutura da classe Aluno que foi gerada. Note que há a navegação entre as classes através da propriedade virtual Professor. Já que é um artigo, vale uma dica do Entity Framework 6.1.1 em relação ao nome da chave primária: o EF entende como chave primária automaticamente se a propriedade se chamar ID ou NomeDaClasseID (AlunoID, ProfessorID). Assim, dispensa o uso do atributo [key] do DataAnnotations ou o PrimaryKey do FluentAPI.
C#
namespace ArtigoCodeFirstMVC5.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Aluno")]
public partial class Aluno
{
public int AlunoID { get; set; }
public int ProfessorID { get; set; }
[Required]
public string NomeAluno { get; set; }
public string Email { get; set; }
public int Ano { get; set; }
public DateTime Inscricao { get; set; }
public virtual Professor Professor { get; set; }
}
}
Criar os controllers e as views
Pronto! Classes e contexto criados, agora o próximo passo é gerar os controllers e as views do projeto. Antes de mais nada e obrigatoriamente, compile o projeto (F6 ou CTRL + SHIFT + B).
Na pasta Controllers, clique com o botão direito e selecione Add / Controller. Conforme a figura 7, selecione a opção “MVC 5 controller with views, using Entity Framework”, ou seja, como temos o DbContext e as classes, vamos basear o template nelas.

Clique no botão Add e conforme a figura 8, selecione a classe Professor em “Model class”, ModeloDados em “Data context class”, selecione o checkbox “Use async controller actions” para gerar todas as Actions como assíncronas. O checkbox “Generate views” irá gerar todas as telas do CRUD completas de acordo com o template do MVC 5. Altere o nome do Controller para ProfessorController, as vezes o VS sugeri o nome da classe no plural e não quero isto.

Clique no botão Add e aguarde o VS gerar todo o Controller (Controllers / ProfessorController.cs) e as Views (veja na pasta Views / Professor), respectivamente. Veja a seguir, parte dos blocos de códigos da classe gerada, afinal não é o foco deste artigo analisar estas classes.
C#
public class ProfessorController : Controller
{
private ModeloDados db = new ModeloDados();
// GET: Professor
public async Task<ActionResult> Index()
{
return View(await db.Professor.ToListAsync());
}
// GET: Professor/Details/5
public async Task<ActionResult> Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Professor professor = await db.Professor.FindAsync(id);
if (professor == null)
{
return HttpNotFound();
}
return View(professor);
}
...
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "ProfessorID,Nome,Telefone,Salario,TwitterBlog,Materia,Disponivel,Admissao")] Professor professor)
{
if (ModelState.IsValid)
{
db.Professor.Add(professor);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(professor);
}
// GET: Professor/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Professor professor = await db.Professor.FindAsync(id);
if (professor == null)
{
return HttpNotFound();
}
return View(professor);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ProfessorID,Nome,Telefone,Salario,TwitterBlog,Materia,Disponivel,Admissao")] Professor professor)
{
if (ModelState.IsValid)
{
db.Entry(professor).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(professor);
}
// GET: Professor/Delete/5
public async Task<ActionResult> Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
...
}
// POST: Professor/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(int id)
{
Professor professor = await db.Professor.FindAsync(id);
db.Professor.Remove(professor);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
}
Repita o mesmo passo para a classe Aluno, conforme figura 9.

Compile o projeto novamente, e para fecharmos o artigo com chave de ouro, abra o arquivo /Views/Shared/_Layout.cshtml e adicione duas linhas na lista de opções do menu para abrirem respectivamente as páginas Index dos Controllers Professor e Aluno.
C#
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("Professor", "Index", "Professor")</li>
<li>@Html.ActionLink("Aluno", "Index", "Aluno")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
Executar a aplicação
Compile novamente o projeto e pressione F5 para executá-la no navegador. Selecione o menu Professor e veja a lista de professores cadastrados, conforme a figura 10.

Conclusão
Produtividade é um tema constante nas discussões dos times de desenvolvimento. Para quem está usando o Entity Framework 6.1.1, vale a pena efetuar testes, escrever códigos para melhorar a performance, verificar os logs gerados no acesso a dados e, é claro, estar atento aos templates gerados, como os deste artigo. Quando pego um projeto para desenvolver ou ajudar um time, sempre uso este recurso de gerar classes a partir do banco existente.
Agradeço a oportunidade de poder compartilhar o conhecimento deste artigo. Qualquer dúvida e preparação de times de desenvolvimento, por favor me contate.




