Neste artigo vamos iniciar a criação de uma aplicação ASP .NET Core MVC usando o Entity Framework Core no Visual Studio 2017.
Esta série de artigos inicia a criação de uma aplicação ASP .NET Core MVC usando o Entity Framework Core com o Visual Studio 2017, e, esta baseada nos artigos originais publicados em https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro com algumas adaptações, traduções e ajustes.
A aplicação de exemplo criada será o site de uma Universidade fictícia que eu vou chamar de Universidade Macoratti e vai incluir funcionalidades como admissão de alunos, criação de cursos e atribuições de instrutores onde iremos usar a ASP .NET Core 1.1 MVC, o Entity Framework Core 1.1 e o Visual Studio 2017.
Você pode baixar a aplicação original neste link : https://github.com/aspnet/Docs/tree/master/aspnetcore/data/ef-mvc/intro/samples/cu-final
Lembrando que o Entity Framework Core 1.1 é a última versão do EF mas ele não possui todos os recursos do Entity Framework 6.x. (Ele esta disponível via nuget: Install-Package Microsoft.EntityFrameworkCore)
O Entity Framework Core (EF Core) é uma versão leve, extensível e multiplataforma do Entity Framework. O EF Core introduz muitas melhorias e novos recursos quando comparado com o EF6.x. O EF Core mantém a experiência do desenvolvedor do EF6.x e a maioria das APIs de alto nível permanecem as mesmas, então o EF Core vai te parecer muito familiar se você conhece o Entity Framework 6.x.
Ao mesmo tempo, o EF Core é construído sobre um conjunto completamente novo de componentes principais. Isso significa que o EF Core não herda automaticamente todos os recursos do EF6.x. Alguns desses recursos serão exibidos em lançamentos futuros (como o lazy loading e a resiliência de conexão), outros recursos menos usados não serão implementados no EF Core. O núcleo novo, extensível e leve também nos permitiu adicionar alguns recursos ao EF Core que não serão implementados no EF6.x.
Para acompanhar este artigo você precisa ter instalado o Visual Studio Community 2017 com os seguintes workloads (cargas de trabalho) instalados:
Criando o projeto Exemplo : Universidade Macoratti no VS Community 2017
A aplicação exemplo que vamos construir nestes tutoriais é um simples site de uma universidade onde os usuários podem visualizar e atualizar informações de alunos, cursos e instrutores, onde iremos focar na utilização do Entity Framework Core.
Vamos iniciar criando uma aplicação ASP .NET Core MVC Web Application.
Abra no VS community 2017 e no menu File clique em New Project;
A seguir selecione o template Visual C# -> .NET Core e marque ASP .NET Core Web Application (.NET Core);
Dessa forma estamos criando uma aplicação web (MVC com views e controllers) usando o framework .NET Core.
Informe o nome UniversidadeMacoratti (ou outro a seu gosto) e clique no botão OK;
Na próxima janela escolha a versão ASP .NET Core 1.1 e marque o template Web Application sem autenticação e clique no botão OK;
Você terá o seguinte projeto criado:
O Visual Studio utiliza um template padrão para o projeto Web Application que é criado e pode ser visto na figura acima.
Temos assim uma aplicação funcional, na verdade , um simples projeto inicial, que será o nosso ponto de partida.
Pressione F5 para rodar a aplicação no modo debug ou Ctrl+F5 para rodar no modo não debug. (O VS inicia o servidor IIS Express e executa a nossa aplicação.)
Observe que o endereço na barra de navegação exibe localhost:14240/ que indica a porta onde a aplicação esta atendendo.
Ajustando o estilo do site
Vamos fazer alguns ajustes iniciais apenas para alterar o menu do site, o seu leiaute e a página incial.
Para isso vamos abrir o arquivo _Layout.cshtml na pasta /Views/Shared e realizar as seguintes alterações:
- Traduzir os textos para o português quando pertinente;
- Alterar o texto UniversidadeMacoratti para Universidade Macoratti;
- Incluir entradas de menu para as seguintes opções : Estudantes, Cursos, Instrutores e Departamentos;
- Deletar a opção Contato do menu;
Abaixo temos as alterações implementadas no arquivo _Layout.cshtml:
@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Universidade Macoratti</title>
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
@Html.Raw(JavaScriptSnippet.FullScript)
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">Universidade Macoratti</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">Sobre</a></li>
<li><a asp-area="" asp-controller="Estudantes" asp-action="Index">Estudantes</a></li>
<li><a asp-area="" asp-controller="Cursos" asp-action="Index">Cursos</a></li>
<li><a asp-area="" asp-controller="Instrutores" asp-action="Index">Instrutores</a></li>
<li><a asp-area="" asp-controller="Departamentos" asp-action="Index">Departamentos</a></li>
</ul>
</div>
</div>
</nav>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2017 - Universidade Macoratti</p>
</footer>
</div>
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("Scripts", required: false)
</body>
</html>
A seguir vamos alterar o código da view Index.cshtml na pasta /Views/Home substituindo o texto existente pelo texto exibido a seguir:
@{
ViewData["Title"] = "Home Page";
}
<div class="jumbotron">
<h1>Universidade Macoratti</h1>
</div>
<div class="row">
<div class="col-md-4">
<h2>Bem-Vindo à Universidade Macoratti</h2>
<p>
Universidade Macoratti é uma aplicação exemplo que
demonstra como usar o Entity Framework Core em uma
aplicação ASP.NET Core MVC web application.
</p>
</div>
<div class="col-md-4">
<h2>Construindo deste o início</h2>
<p>Você pode criar a aplicação seguindo os seguintes passos nesta série de tutoriais.</p>
<p><a class="btn btn-default" href="https://docs.asp.net/en/latest/data/ef-mvc/intro.html">Veja o tutorial »</a></p>
</div>
<div class="col-md-4">
<h2>Baixe o projeto completo</h2>
<p>Você pode baixar o projeto completo do GitHub.</p>
<p><a class="btn btn-default" href="https://github.com/aspnet/Docs/tree/master/aspnet/data/ef-mvc/intro/samples/cu-final">Veja o código fonte do projeto »</a></p>
</div>
</div>
Após fazer essas alterações executando novamente a aplicação (F5 ou CTRL+F5) teremos o seguinte resultado:
Simplificamos assim o leiaute da aplicação. Vamos agora incluir o suporte ao Entity Framework Core em nossa aplicação.
Adicionando o suporte para o Entity Framework Core via Nuget
Vamos adicionar o suporte ao EF Core em nosso projeto e instalar o provedor do banco de dados que vamos usar. No exemplo deste artigo vamos instalar o provedor SQL Server : Microsoft.EntityFrameworkCore.SqlServer.
Para instalar esse pacote abra uma janela do Package Manager Console via menu Tools e digite o comando : Install-Package Microsoft.EntityFrameworkCore.SqlServer
Este pacote e suas dependências (Microsoft.EntityFrameworkCore e Microsoft.EntityFrameworkCore.Relational) fornece o suporte em tempo de execução ao EF.(Mais adiante iremos instalar outro pacote para a migração)
Nota: O EF para no .NET Core não possui todas as funcionalidades do EF 6. (lazy loading não esta suportado ainda)
Criando o nosso modelo de dados
Agora que temos o suporte ao EF Core vamos criar as classes das entidades para a nossa aplicação. Vamos inciar com as seguintes três entidades :
Neste modelo temos que :
- Existe um relacionamento um-para-muitos entre as entidades Estudante e Matricula
- Existe um relacionamento um-para-muitos entre as entidades Curso e Matricula
Dessa forma um estudante pode estar matriculado em qualquer número de cursos e um curso pode ter qualquer número de estudantes matriculados.
Vamos agora criar classes que representam as nossas entidades.
1- Criando a entidade Estudante
Vamos criar uma pasta chamada “Models” no projeto para nesta pasta definir o modelo de entidades.
Nota: Você pode colocar classes do modelo em qualquer lugar em seu projeto, mas a pasta Models é usada por convenção.
Na janela Solution Explorer, clique com o botão direito do mouse no projeto e selecione Add -> New Folder e informe o nome Models.
As classes são criadas na pasta Models clicando com o botão direito sobre a pasta, selecionando Add -> Class e a seguir informando o nome da classe.
Vamos iniciar criando o arquivo Estudante.cs e nele vamos definir a classe Estudante conforme abaixo:
using System;
using System.Collections.Generic;
namespace UniversidadeMacoratti.Models
{
public class Estudante
{
public int EstudanteID { get; set; }
public string SobreNome { get; set; }
public string Nome { get; set; }
public DateTime DataMatricula { get; set; }
public ICollection<Matricula> Matriculas { get; set; }
}
}
A propriedade EstudanteID será a coluna de chave primária da tabela de banco de dados que corresponde a essa classe. Por padrão, o Entity Framework interpreta uma propriedade que é chamada de ID ou nome_classeID como sendo a chave primária.(Podemos alterar esse comportamento com annotations)
A propriedade de Matricula é uma propriedade de navegação. As propriedades de navegação tratam outras entidades que estão relacionadas com esta entidade permitindo que acessemos propriedades relacionadas.
Neste caso, a propriedade Matriculas da entidade Estudante irá tratar todas as entidades Matricula que estão relacionadas com essa entidade Estudante. Ou seja , se um registro de estudante na base de dados possuir dois registros matricula relacionados, a propriedades de navegação Matriculas da entidade Estudante irá conter as duas entidades Matricula.
Se uma propriedade de navegação pode conter várias entidades (como nas relações many-to-many ou one-to-many), seu tipo deve ser uma lista na qual as entradas podem ser adicionadas, excluídas e atualizadas, como ICollection<T>. Você pode especificar ICollection<T> ou um tipo como uma List<T> ou HashSet<T>. Se você especificar ICollection<T>, o EF cria uma coleção HashSet<T> por padrão.
2- Criando a entidade Matricula
Na mesma pasta Models vamos criar a classe Matricula.cs e definir o código da classe Matricula conforme abaixo:
namespace UniversidadeMacoratti.Models
{
public enum Nota
{
A, B, C, D, F
}
public class Matricula
{
public int MatriculaID { get; set; }
public int CursoID { get; set; }
public int EstudanteID { get; set; }
public Nota? Nota { get; set; }
public Curso Curso { get; set; }
public Estudante Estudante { get; set; }
}
}
A propriedade MatriculaID será a chave primária; Essa entidade usa o padrão classnameID em vez de ID por si mesmo como fizemos na entidade Estudante. É bom você escolher um padrão e usar esse padrão em todo o seu modelo de dados. Aqui, a variação ilustra que você pode usar qualquer padrão. Em um tutorial posterior, você verá como o uso de ID sem classname torna mais fácil implementar a herança no modelo de dados.
A propriedade Nota um enum. O ponto de interrogação após a declaração de tipo Nota indica que a propriedade Nota é anulável. Uma nota que é nula é diferente de uma nota zero – nula significa que uma nota não é conhecida ou ainda não foi atribuída.
A propriedade EstudanteID é uma chave estrangeira e a propriedade de navegação correspondente é Estudante. Uma entidade Matricula está associada a uma entidade Estudante, de modo que a propriedade só pode conter uma única entidade Estudante (ao contrário da propriedade de navegação Estudante.Matriculas que você viu anteriormente, que pode conter várias entidades Matricula.
A propriedade CursoID é uma chave estrangeira e a propriedade de navegação correspondente é Curso. Uma entidade Matricula está associada a uma entidade Curso.
O Entity Framework interpreta uma propriedade como uma propriedade de chave estrangeira se ela for nomeada assim : <nome da propriedade de navegação><nome da propriedade da chave primária> (Ex: EstudanteID para a propriedade de navegação do Estudante, uma vez que a chave primária da entidade Estudante é ID).
As propriedades de chave estrangeira também podem ser nomeadas simplesmente assim: <nome da propriedade da chave primária> (Ex: CursoID, uma vez que a chave principal da Curso é CursoID).
3- Criando a entidade Curso
Na mesma pasta Models vamos criar a classe Curso.cs e definir o código da classe Curso conforme abaixo:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace UniversidadeMacoratti.Models
{
public class Curso
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CursoID { get; set; }
public string Titulo { get; set; }
public int Creditos { get; set; }
public ICollection<Matricula> Matriculas { get; set; }
}
}
O atributo [DatabaseGenerated] é usado em campos computados e quando definido com a opção DatabaseGeneratedOption.None faz com que o banco de dados não gere um valor para a propriedade quando linhas forem inseridas ou atualizadas na respectiva tabela.
No caso ela esta sendo usada para que a propriedade CursoID não seja definida como um campo Identity pelo SQL Server.
Estamos usando a abordagem Code-First do Entity Framework e nesta abordagem escrevemos as nossas classes POCO em primeiro lugar e, em seguida, o EF cria o banco de dados a partir dessas classes POCO (Plain Old CLR Objects).
Dessa forma, quando decidimos usar o Code-First não precisamos começar nossa aplicação criando o banco de dados ou definindo um esquema mas podemos iniciar escrevendo classes .NET para definir o modelo de objetos do nosso domínio sem ter que misturar a lógica de persistência de dados com as classes.
Nota : O Entity Framework por padrão adota algumas convenções (Conventions) que ele usa para realizar algumas operações.
Dessa forma temos o nosso modelo de entidades pronto e vamos continuar a próxima parte do artigo criando o contexto do banco de dados e definindo os dados de testes que iremos usar.













