ASP.NET Core MVC com o Entity Framework Core – tutorial – 1 de 10ASP.NET Core MVC with Entity Framework Core - Tutorial 1 of 10

Este tutorial não foi atualizado para o ASP.NET Core 2.1.This tutorial has not been upgraded to ASP.NET Core 2.1. A versão deste tutorial para o ASP.NET Core 2.0 pode ser consultada selecionando ASP.NET Core 2.0 acima do sumário ou na parte superior da página:The ASP.NET Core 2.0 version of this tutorial is available by selecting ASP.NET Core 2.0 above the table of contents or at the top of the page:

A versão deste tutorial do Razor Pages para o ASP.NET Core 2.1 conta com várias melhorias em relação à versão 2.0.The ASP.NET Core 2.1 Razor Pages version of this tutorial has many improvements over the 2.0 version.

O tutorial do 2.0 ensina a usar o ASP.NET Core MVC e o Entity Framework Core com controladores e exibições.The 2.0 tutorial teaches ASP.NET Core MVC and Entity Framework Core with controllers and views. O Razor Pages é um modelo de programação baseado em página que torna a criação da interface do usuário da Web mais fácil e produtiva.Razor Pages is a page-based programming model that makes building web UI easier and more productive. É recomendável tentar o tutorial das Páginas Razor na versão do MVC.We recommend the Razor Pages tutorial over the MVC version. O tutorial Páginas do Razor:The Razor Pages tutorial:

  • É mais fácil de acompanhar.Is easier to follow. Por exemplo, o código de scaffolding foi bastante simplificado.For example, the scaffolding code has been significantly simplified.
  • Fornece mais práticas recomendadas do EF Core.Provides more EF Core best practices.
  • Usa consultas mais eficientes.Uses more efficient queries.
  • É mais atual com a API mais recente.Is more current with the latest API.
  • Aborda mais recursos.Covers more features.
  • É a abordagem preferencial para o desenvolvimento de novos aplicativos.Is the preferred approach for new application development.

Se você escolher este tutorial em vez da versão Razor Pages, deixe uma observação explicando o motivo nesta discussão do GitHub.If you choose this tutorial over the Razor Pages version, let us know why in this GitHub discussion.

Por Tom Dykstra e Rick AndersonBy Tom Dykstra and Rick Anderson

Este tutorial ensina a usar o ASP.NET Core MVC e o Entity Framework Core com controladores e exibições.This tutorial teaches ASP.NET Core MVC and Entity Framework Core with controllers and views. As Páginas Razor é uma nova alternativa no ASP.NET Core 2.0, um modelo de programação baseado em página que torna a criação da interface do usuário da Web mais fácil e produtiva.Razor Pages is a new alternative in ASP.NET Core 2.0, a page-based programming model that makes building web UI easier and more productive. É recomendável tentar o tutorial das Páginas Razor na versão do MVC.We recommend the Razor Pages tutorial over the MVC version. O tutorial Páginas do Razor:The Razor Pages tutorial:

  • É mais fácil de acompanhar.Is easier to follow.
  • Fornece mais práticas recomendadas do EF Core.Provides more EF Core best practices.
  • Usa consultas mais eficientes.Uses more efficient queries.
  • É mais atual com a API mais recente.Is more current with the latest API.
  • Aborda mais recursos.Covers more features.
  • É a abordagem preferencial para o desenvolvimento de novos aplicativos.Is the preferred approach for new application development.

Se você escolher este tutorial em vez da versão Páginas do Razor, deixe uma observação explicando o motivo neste problema do GitHub.If you choose this tutorial over the Razor Pages version, let us know why in this GitHub issue.

O aplicativo Web de exemplo Contoso University demonstra como criar aplicativos Web ASP.NET Core 2.0 MVC usando o EF (Entity Framework) Core 2.0 e o Visual Studio 2017.The Contoso University sample web application demonstrates how to create ASP.NET Core 2.0 MVC web applications using Entity Framework (EF) Core 2.0 and Visual Studio 2017.

O aplicativo de exemplo é um site de uma Contoso University fictícia.The sample application is a web site for a fictional Contoso University. Ele inclui funcionalidades como admissão de alunos, criação de cursos e atribuições de instrutor.It includes functionality such as student admission, course creation, and instructor assignments. Este é o primeiro de uma série de tutoriais que explica como criar o aplicativo de exemplo Contoso University do zero.This is the first in a series of tutorials that explain how to build the Contoso University sample application from scratch.

Baixe ou exiba o aplicativo concluído.Download or view the completed application.

O EF Core 2.0 é a última versão do EF, mas ainda não tem todos os recursos do EF 6.x.EF Core 2.0 is the latest version of EF but doesn't yet have all the features of EF 6.x. Para obter informações sobre como escolher entre o EF 6.x e o EF Core, consulte EF Core vs. EF6.x.For information about how to choose between EF 6.x and EF Core, see EF Core vs. EF6.x. Se você escolher o EF 6.x, confira a versão anterior desta série de tutoriais.If you choose EF 6.x, see the previous version of this tutorial series.

Observação

Para obter a versão ASP.NET Core 1.1 deste tutorial, confira a versão VS 2017 Atualização 2 deste tutorial em formato PDF.For the ASP.NET Core 1.1 version of this tutorial, see the VS 2017 Update 2 version of this tutorial in PDF format.

Pré-requisitosPrerequisites

Clique em uma das seguintes opções:Install one of the following:

Solução de problemasTroubleshooting

Caso tenha um problema que não consiga resolver, em geral, você poderá encontrar a solução comparando o código com o projeto concluído.If you run into a problem you can't resolve, you can generally find the solution by comparing your code to the completed project. Para obter uma lista de erros comuns e como resolvê-los, consulte a seção Solução de problemas do último tutorial da série.For a list of common errors and how to solve them, see the Troubleshooting section of the last tutorial in the series. Caso não encontre o que precisa na seção, poste uma pergunta no StackOverflow.com sobre o ASP.NET Core ou o EF Core.If you don't find what you need there, you can post a question to StackOverflow.com for ASP.NET Core or EF Core.

Dica

Esta é uma série de dez tutoriais, cada um se baseando no que é feito nos tutoriais anteriores.This is a series of 10 tutorials, each of which builds on what is done in earlier tutorials. Considere a possibilidade de salvar uma cópia do projeto após a conclusão bem-sucedida de cada tutorial.Consider saving a copy of the project after each successful tutorial completion. Caso tenha problemas, comece novamente no tutorial anterior em vez de voltar ao início de toda a série.Then if you run into problems, you can start over from the previous tutorial instead of going back to the beginning of the whole series.

O aplicativo Web Contoso UniversityThe Contoso University web application

O aplicativo que você criará nestes tutoriais é um site simples de uma universidade.The application you'll be building in these tutorials is a simple university web site.

Os usuários podem exibir e atualizar informações de alunos, cursos e instrutores.Users can view and update student, course, and instructor information. Estas são algumas das telas que você criará.Here are a few of the screens you'll create.

Página Índice de Alunos

Página Editar Alunos

O estilo de interface do usuário desse site foi mantido perto do que é gerado pelos modelos internos, de modo que o tutorial possa se concentrar principalmente em como usar o Entity Framework.The UI style of this site has been kept close to what's generated by the built-in templates, so that the tutorial can focus mainly on how to use the Entity Framework.

Criar um aplicativo Web ASP.NET Core MVCCreate an ASP.NET Core MVC web application

Abra o Visual Studio e crie um novo projeto Web ASP.NET Core C# chamado "ContosoUniversity".Open Visual Studio and create a new ASP.NET Core C# web project named "ContosoUniversity".

  • No menu Arquivo, selecione Novo > Projeto.From the File menu, select New > Project.

  • No painel esquerdo, selecione Instalado > Visual C# > Web.From the left pane, select Installed > Visual C# > Web.

  • Selecione o modelo de projeto Aplicativo Web ASP.NET Core.Select the ASP.NET Core Web Application project template.

  • Insira ContosoUniversity como o nome e clique em OK.Enter ContosoUniversity as the name and click OK.

    Caixa de diálogo Novo Projeto

  • Aguarde a caixa de diálogo Novo Aplicativo Web ASP.NET Core (.NET Core) ser exibidaWait for the New ASP.NET Core Web Application (.NET Core) dialog to appear

  • Selecione ASP.NET Core 2.0 e o modelo Aplicativo Web (Model-View-Controller).Select ASP.NET Core 2.0 and the Web Application (Model-View-Controller) template.

    Observação: este tutorial exige o ASP.NET Core 2.0 e o EF Core 2.0 ou posterior — verifique se ASP.NET Core 1.1 não está selecionado.Note: This tutorial requires ASP.NET Core 2.0 and EF Core 2.0 or later -- make sure that ASP.NET Core 1.1 isn't selected.

  • Verifique se a opção Autenticação está definida como Sem Autenticação.Make sure Authentication is set to No Authentication.

  • Clique em OKClick OK

    Caixa de diálogo Novo projeto ASP.NET Core

Configurar o estilo do siteSet up the site style

Algumas alterações simples configurarão o menu do site, o layout e a home page.A few simple changes will set up the site menu, layout, and home page.

Abra Views/Shared/_Layout.cshtml e faça as seguintes alterações:Open Views/Shared/_Layout.cshtml and make the following changes:

  • Altere cada ocorrência de "ContosoUniversity" para "Contoso University".Change each occurrence of "ContosoUniversity" to "Contoso University". Há três ocorrências.There are three occurrences.

  • Adicione entradas de menu para Alunos, Cursos, Instrutores e Departamentos e exclua a entrada de menu Contato.Add menu entries for Students, Courses, Instructors, and Departments, and delete the Contact menu entry.

As alterações são realçadas.The changes are highlighted.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Contoso University</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>
    
</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">Contoso University</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">About</a></li>
                    <li><a asp-area="" asp-controller="Students" asp-action="Index">Students</a></li>
                    <li><a asp-area="" asp-controller="Courses" asp-action="Index">Courses</a></li>
                    <li><a asp-area="" asp-controller="Instructors" asp-action="Index">Instructors</a></li>
                    <li><a asp-area="" asp-controller="Departments" asp-action="Index">Departments</a></li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2017 - Contoso University</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>

Em Views/Home/Index.cshtml, substitua o conteúdo do arquivo pelo seguinte código para substituir o texto sobre o ASP.NET e MVC pelo texto sobre este aplicativo:In Views/Home/Index.cshtml, replace the contents of the file with the following code to replace the text about ASP.NET and MVC with text about this application:

@{
    ViewData["Title"] = "Home Page";
}

<div class="jumbotron">
    <h1>Contoso University</h1>
</div>
<div class="row">
    <div class="col-md-4">
        <h2>Welcome to Contoso University</h2>
        <p>
            Contoso University is a sample application that
            demonstrates how to use Entity Framework Core in an
            ASP.NET Core MVC web application.
        </p>
    </div>
    <div class="col-md-4">
        <h2>Build it from scratch</h2>
        <p>You can build the application by following the steps in a series of tutorials.</p>
        <p><a class="btn btn-default" href="https://docs.asp.net/en/latest/data/ef-mvc/intro.html">See the tutorial &raquo;</a></p>
    </div>
    <div class="col-md-4">
        <h2>Download it</h2>
        <p>You can download the completed project from GitHub.</p>
        <p><a class="btn btn-default" href="https://github.com/aspnet/Docs/tree/master/aspnetcore/data/ef-mvc/intro/samples/cu-final">See project source code &raquo;</a></p>
    </div>
</div>

Pressione CTRL+F5 para executar o projeto ou escolha Depurar > Iniciar sem Depuração no menu.Press CTRL+F5 to run the project or choose Debug > Start Without Debugging from the menu. Você verá a home page com guias para as páginas que você criará nestes tutoriais.You see the home page with tabs for the pages you'll create in these tutorials.

Home page da Contoso University

Pacotes NuGet do Entity Framework CoreEntity Framework Core NuGet packages

Para adicionar o suporte do EF Core a um projeto, instale o provedor de banco de dados que você deseja ter como destino.To add EF Core support to a project, install the database provider that you want to target. Este tutorial usa o SQL Server e o pacote de provedor é Microsoft.EntityFrameworkCore.SqlServer.This tutorial uses SQL Server, and the provider package is Microsoft.EntityFrameworkCore.SqlServer. Esse pacote está incluído no metapacote Microsoft.AspNetCore.App, portanto você não precisa referenciar o pacote se o aplicativo tem uma referência de pacote ao pacote Microsoft.AspNetCore.App.This package is included in the Microsoft.AspNetCore.App metapackage, so you don't need to reference the package if your app has a package reference for the Microsoft.AspNetCore.App package.

Este pacote e suas dependências (Microsoft.EntityFrameworkCore e Microsoft.EntityFrameworkCore.Relational) fornecem suporte de tempo de execução para o EF.This package and its dependencies (Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Relational) provide runtime support for EF. Você adicionará um pacote de ferramentas posteriormente, no tutorial Migrações.You'll add a tooling package later, in the Migrations tutorial.

Para obter informações sobre outros provedores de banco de dados que estão disponíveis para o Entity Framework Core, consulte Provedores de banco de dados.For information about other database providers that are available for Entity Framework Core, see Database providers.

Criar o modelo de dadosCreate the data model

Em seguida, você criará as classes de entidade para o aplicativo Contoso University.Next you'll create entity classes for the Contoso University application. Você começará com as três entidades a seguir.You'll start with the following three entities.

Diagrama de Modelo de Dados Course-Enrollment-Student

Há uma relação um-para-muitos entre as entidades Student e Enrollment, e uma relação um-para-muitos entre as entidades Course e Enrollment.There's a one-to-many relationship between Student and Enrollment entities, and there's a one-to-many relationship between Course and Enrollment entities. Em outras palavras, um aluno pode ser registrado em qualquer quantidade de cursos e um curso pode ter qualquer quantidade de alunos registrados.In other words, a student can be enrolled in any number of courses, and a course can have any number of students enrolled in it.

Nas seções a seguir, você criará uma classe para cada uma dessas entidades.In the following sections you'll create a class for each one of these entities.

A entidade StudentThe Student entity

Diagrama da entidade Student

Na pasta Models, crie um arquivo de classe chamado Student.cs e substitua o código de modelo pelo código a seguir.In the Models folder, create a class file named Student.cs and replace the template code with the following code.

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

A propriedade ID se tornará a coluna de chave primária da tabela de banco de dados que corresponde a essa classe.The ID property will become the primary key column of the database table that corresponds to this class. Por padrão, o Entity Framework interpreta uma propriedade nomeada ID ou classnameID como a chave primária.By default, the Entity Framework interprets a property that's named ID or classnameID as the primary key.

A propriedade Enrollments é uma propriedade de navegação.The Enrollments property is a navigation property. As propriedades de navegação armazenam outras entidades que estão relacionadas a essa entidade.Navigation properties hold other entities that are related to this entity. Nesse caso, a propriedade Enrollments de uma Student entity armazenará todas as entidades Enrollment relacionadas a essa entidade Student.In this case, the Enrollments property of a Student entity will hold all of the Enrollment entities that are related to that Student entity. Em outras palavras, se determinada linha Aluno no banco de dados tiver duas linhas Registro relacionadas (linhas que contêm o valor de chave primária do aluno na coluna de chave estrangeira StudentID), a propriedade de navegação Enrollments dessa entidade Student conterá as duas entidades Enrollment.In other words, if a given Student row in the database has two related Enrollment rows (rows that contain that student's primary key value in their StudentID foreign key column), that Student entity's Enrollments navigation property will contain those two Enrollment entities.

Se uma propriedade de navegação pode armazenar várias entidades (como em relações muitos para muitos ou um-para-muitos), o tipo precisa ser uma lista na qual entradas podem ser adicionadas, excluídas e atualizadas, como ICollection<T>.If a navigation property can hold multiple entities (as in many-to-many or one-to-many relationships), its type must be a list in which entries can be added, deleted, and updated, such as ICollection<T>. Especifique ICollection<T> ou um tipo, como List<T> ou HashSet<T>.You can specify ICollection<T> or a type such as List<T> or HashSet<T>. Se você especificar ICollection<T>, o EF criará uma coleção HashSet<T> por padrão.If you specify ICollection<T>, EF creates a HashSet<T> collection by default.

A entidade EnrollmentThe Enrollment entity

Diagrama da entidade Enrollment

Na pasta Models, crie Enrollment.cs e substitua o código existente pelo seguinte código:In the Models folder, create Enrollment.cs and replace the existing code with the following code:

namespace ContosoUniversity.Models
{
    public enum Grade
    {
        A, B, C, D, F
    }

    public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        public Grade? Grade { get; set; }

        public Course Course { get; set; }
        public Student Student { get; set; }
    }
}

A propriedade EnrollmentID será a chave primária; essa entidade usa o padrão classnameID em vez de ID por si só, como você viu na entidade Student.The EnrollmentID property will be the primary key; this entity uses the classnameID pattern instead of ID by itself as you saw in the Student entity. Normalmente, você escolhe um padrão e usa-o em todo o modelo de dados.Ordinarily you would choose one pattern and use it throughout your data model. Aqui, a variação ilustra que você pode usar qualquer um dos padrões.Here, the variation illustrates that you can use either pattern. Em um tutorial posterior, você verá como usar uma ID sem nome de classe facilita a implementação da herança no modelo de dados.In a later tutorial, you'll see how using ID without classname makes it easier to implement inheritance in the data model.

A propriedade Grade é um enum.The Grade property is an enum. O ponto de interrogação após a declaração de tipo Grade indica que a propriedade Grade permite valor nulo.The question mark after the Grade type declaration indicates that the Grade property is nullable. Uma nota nula é diferente de uma nota zero – nulo significa que uma nota não é conhecida ou que ainda não foi atribuída.A grade that's null is different from a zero grade -- null means a grade isn't known or hasn't been assigned yet.

A propriedade StudentID é uma chave estrangeira e a propriedade de navegação correspondente é Student.The StudentID property is a foreign key, and the corresponding navigation property is Student. Uma entidade Enrollment é associada a uma entidade Student, de modo que a propriedade possa armazenar apenas uma única entidade Student (ao contrário da propriedade de navegação Student.Enrollments que você viu anteriormente, que pode armazenar várias entidades Enrollment).An Enrollment entity is associated with one Student entity, so the property can only hold a single Student entity (unlike the Student.Enrollments navigation property you saw earlier, which can hold multiple Enrollment entities).

A propriedade CourseID é uma chave estrangeira e a propriedade de navegação correspondente é Course.The CourseID property is a foreign key, and the corresponding navigation property is Course. Uma entidade Enrollment está associada a uma entidade Course.An Enrollment entity is associated with one Course entity.

O Entity Framework interpreta uma propriedade como uma propriedade de chave estrangeira se ela é nomeada <navigation property name><primary key property name> (por exemplo, StudentID para a propriedade de navegação Student, pois a chave primária da entidade Student é ID).Entity Framework interprets a property as a foreign key property if it's named <navigation property name><primary key property name> (for example, StudentID for the Student navigation property since the Student entity's primary key is ID). As propriedades de chave estrangeira também podem ser nomeadas apenas <primary key property name> (por exemplo, CourseID, pois a chave primária da entidade Course é CourseID).Foreign key properties can also be named simply <primary key property name> (for example, CourseID since the Course entity's primary key is CourseID).

A entidade CourseThe Course entity

Diagrama de entidade Curso

Na pasta Models, crie Course.cs e substitua o código existente pelo seguinte código:In the Models folder, create Course.cs and replace the existing code with the following code:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

A propriedade Enrollments é uma propriedade de navegação.The Enrollments property is a navigation property. Uma entidade Course pode estar relacionada a qualquer quantidade de entidades Enrollment.A Course entity can be related to any number of Enrollment entities.

Falaremos mais sobre o atributo DatabaseGenerated em um tutorial posterior desta série.We'll say more about the DatabaseGenerated attribute in a later tutorial in this series. Basicamente, esse atributo permite que você insira a chave primária do curso, em vez de fazer com que ela seja gerada pelo banco de dados.Basically, this attribute lets you enter the primary key for the course rather than having the database generate it.

Criar o contexto de banco de dadosCreate the Database Context

A classe principal que coordena a funcionalidade do Entity Framework para determinado modelo de dados é a classe de contexto de banco de dados.The main class that coordinates Entity Framework functionality for a given data model is the database context class. Você cria essa classe derivando-a da classe Microsoft.EntityFrameworkCore.DbContext.You create this class by deriving from the Microsoft.EntityFrameworkCore.DbContext class. No código, especifique quais entidades são incluídas no modelo de dados.In your code you specify which entities are included in the data model. Também personalize o comportamento específico do Entity Framework.You can also customize certain Entity Framework behavior. Neste projeto, a classe é chamada SchoolContext.In this project, the class is named SchoolContext.

Na pasta do projeto, crie uma pasta chamada Dados.In the project folder, create a folder named Data.

Na pasta Dados, crie um novo arquivo de classe chamado SchoolContext.cs e substitua o código de modelo pelo seguinte código:In the Data folder create a new class file named SchoolContext.cs, and replace the template code with the following code:

using ContosoUniversity.Models;
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity.Data
{
    public class SchoolContext : DbContext
    {
        public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }

        public DbSet<Course> Courses { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Student> Students { get; set; }
    }
}

Esse código cria uma propriedade DbSet para cada conjunto de entidades.This code creates a DbSet property for each entity set. Na terminologia do Entity Framework, um conjunto de entidades normalmente corresponde a uma tabela de banco de dados, enquanto uma entidade corresponde a uma linha na tabela.In Entity Framework terminology, an entity set typically corresponds to a database table, and an entity corresponds to a row in the table.

Você pode omitir as instruções DbSet<Enrollment> e DbSet<Course> e elas funcionarão da mesma maneira.You could've omitted the DbSet<Enrollment> and DbSet<Course> statements and it would work the same. O Entity Framework inclui-os de forma implícita porque a entidade Student referencia a entidade Enrollment e a entidade Enrollment referencia a entidade Course.The Entity Framework would include them implicitly because the Student entity references the Enrollment entity and the Enrollment entity references the Course entity.

Quando o banco de dados é criado, o EF cria tabelas que têm nomes iguais aos nomes de propriedade DbSet.When the database is created, EF creates tables that have names the same as the DbSet property names. Em geral, os nomes de propriedade de coleções são plurais (Alunos em vez de Aluno), mas os desenvolvedores não concordam sobre se os nomes de tabela devem ser pluralizados ou não.Property names for collections are typically plural (Students rather than Student), but developers disagree about whether table names should be pluralized or not. Para esses tutoriais, você substituirá o comportamento padrão especificando nomes singulares de tabela no DbContext.For these tutorials you'll override the default behavior by specifying singular table names in the DbContext. Para fazer isso, adicione o código realçado a seguir após a última propriedade DbSet.To do that, add the following highlighted code after the last DbSet property.

using ContosoUniversity.Models;
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity.Data
{
    public class SchoolContext : DbContext
    {
        public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }

        public DbSet<Course> Courses { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Student> Students { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Course>().ToTable("Course");
            modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
            modelBuilder.Entity<Student>().ToTable("Student");
        }
    }
}

Registrar o contexto com a injeção de dependênciaRegister the context with dependency injection

O ASP.NET Core implementa a injeção de dependência por padrão.ASP.NET Core implements dependency injection by default. Serviços (como o contexto de banco de dados do EF) são registrados com injeção de dependência durante a inicialização do aplicativo.Services (such as the EF database context) are registered with dependency injection during application startup. Os componentes que exigem esses serviços (como controladores MVC) recebem esses serviços por meio de parâmetros do construtor.Components that require these services (such as MVC controllers) are provided these services via constructor parameters. Você verá o código de construtor do controlador que obtém uma instância de contexto mais adiante neste tutorial.You'll see the controller constructor code that gets a context instance later in this tutorial.

Para registrar SchoolContext como um serviço, abra Startup.cs e adicione as linhas realçadas ao método ConfigureServices.To register SchoolContext as a service, open Startup.cs, and add the highlighted lines to the ConfigureServices method.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SchoolContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddMvc();
}

O nome da cadeia de conexão é passado para o contexto com a chamada de um método em um objeto DbContextOptionsBuilder.The name of the connection string is passed in to the context by calling a method on a DbContextOptionsBuilder object. Para o desenvolvimento local, o sistema de configuração do ASP.NET Core lê a cadeia de conexão do arquivo appsettings.json.For local development, the ASP.NET Core configuration system reads the connection string from the appsettings.json file.

Adicione instruções using aos namespaces ContosoUniversity.Data e Microsoft.EntityFrameworkCore e, em seguida, compile o projeto.Add using statements for ContosoUniversity.Data and Microsoft.EntityFrameworkCore namespaces, and then build the project.

using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;

Abra o arquivo appsettings.json e adicione uma cadeia de conexão, conforme mostrado no exemplo a seguir.Open the appsettings.json file and add a connection string as shown in the following example.

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

SQL Server Express LocalDBSQL Server Express LocalDB

A cadeia de conexão especifica um banco de dados LocalDB do SQL Server.The connection string specifies a SQL Server LocalDB database. LocalDB é uma versão leve do Mecanismo de Banco de Dados do SQL Server Express destinado ao desenvolvimento de aplicativos, e não ao uso em produção.LocalDB is a lightweight version of the SQL Server Express Database Engine and is intended for application development, not production use. O LocalDB é iniciado sob demanda e executado no modo de usuário e, portanto, não há nenhuma configuração complexa.LocalDB starts on demand and runs in user mode, so there's no complex configuration. Por padrão, o LocalDB cria arquivos de banco de dados .mdf no diretório C:/Users/<user>.By default, LocalDB creates .mdf database files in the C:/Users/<user> directory.

Adicionar um código para inicializar o banco de dados com os dados de testeAdd code to initialize the database with test data

O Entity Framework criará um banco de dados vazio para você.The Entity Framework will create an empty database for you. Nesta seção, você escreve um método que é chamado depois que o banco de dados é criado para populá-lo com os dados de teste.In this section, you write a method that's called after the database is created in order to populate it with test data.

Aqui, você usará o método EnsureCreated para criar o banco de dados automaticamente.Here you'll use the EnsureCreated method to automatically create the database. Em um tutorial posterior, você verá como manipular as alterações do modelo usando as Migrações do Code First para alterar o esquema de banco de dados, em vez de remover e recriar o banco de dados.In a later tutorial you'll see how to handle model changes by using Code First Migrations to change the database schema instead of dropping and re-creating the database.

Na pasta Data, crie um novo arquivo de classe chamado DbInitializer.cs e substitua o código de modelo pelo código a seguir, que faz com que um banco de dados seja criado, quando necessário, e carrega dados de teste no novo banco de dados.In the Data folder, create a new class file named DbInitializer.cs and replace the template code with the following code, which causes a database to be created when needed and loads test data into the new database.

using ContosoUniversity.Models;
using System;
using System.Linq;

namespace ContosoUniversity.Data
{
    public static class DbInitializer
    {
        public static void Initialize(SchoolContext context)
        {
            context.Database.EnsureCreated();

            // Look for any students.
            if (context.Students.Any())
            {
                return;   // DB has been seeded
            }

            var students = new Student[]
            {
            new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
            new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
            new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
            new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
            new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
            };
            foreach (Student s in students)
            {
                context.Students.Add(s);
            }
            context.SaveChanges();

            var courses = new Course[]
            {
            new Course{CourseID=1050,Title="Chemistry",Credits=3},
            new Course{CourseID=4022,Title="Microeconomics",Credits=3},
            new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
            new Course{CourseID=1045,Title="Calculus",Credits=4},
            new Course{CourseID=3141,Title="Trigonometry",Credits=4},
            new Course{CourseID=2021,Title="Composition",Credits=3},
            new Course{CourseID=2042,Title="Literature",Credits=4}
            };
            foreach (Course c in courses)
            {
                context.Courses.Add(c);
            }
            context.SaveChanges();

            var enrollments = new Enrollment[]
            {
            new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
            new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
            new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
            new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
            new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
            new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
            new Enrollment{StudentID=3,CourseID=1050},
            new Enrollment{StudentID=4,CourseID=1050},
            new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
            new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
            new Enrollment{StudentID=6,CourseID=1045},
            new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
            };
            foreach (Enrollment e in enrollments)
            {
                context.Enrollments.Add(e);
            }
            context.SaveChanges();
        }
    }
}

O código verifica se há alunos no banco de dados e, se não há, ele pressupõe que o banco de dados é novo e precisa ser propagado com os dados de teste.The code checks if there are any students in the database, and if not, it assumes the database is new and needs to be seeded with test data. Ele carrega os dados de teste em matrizes em vez de em coleções List<T> para otimizar o desempenho.It loads test data into arrays rather than List<T> collections to optimize performance.

Em Program.cs, modifique o método Main para fazer o seguinte na inicialização do aplicativo:In Program.cs, modify the Main method to do the following on application startup:

  • Obtenha uma instância de contexto de banco de dados do contêiner de injeção de dependência.Get a database context instance from the dependency injection container.
  • Chame o método de semente passando a ele o contexto.Call the seed method, passing to it the context.
  • Descarte o contexto quando o método de semente for concluído.Dispose the context when the seed method is done.
public static void Main(string[] args)
{
    var host = BuildWebHost(args);

    using (var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<SchoolContext>();
            DbInitializer.Initialize(context);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while seeding the database.");
        }
    }

    host.Run();
}

Adicione instruções using:Add using statements:

using Microsoft.Extensions.DependencyInjection;
using ContosoUniversity.Data;

Nos tutoriais mais antigos, você poderá ver um código semelhante no método Configure em Startup.cs.In older tutorials, you may see similar code in the Configure method in Startup.cs. Recomendamos que você use o método Configure apenas para configurar o pipeline de solicitação.We recommend that you use the Configure method only to set up the request pipeline. O código de inicialização do aplicativo pertence ao método Main.Application startup code belongs in the Main method.

Agora, na primeira vez que você executar o aplicativo, o banco de dados será criado e propagado com os dados de teste.Now the first time you run the application, the database will be created and seeded with test data. Sempre que você alterar o modelo de dados, exclua o banco de dados, atualize o método de semente e comece novamente com um novo banco de dados da mesma maneira.Whenever you change your data model, you can delete the database, update your seed method, and start afresh with a new database the same way. Nos próximos tutoriais, você verá como modificar o banco de dados quando o modelo de dados for alterado, sem excluí-lo e recriá-lo.In later tutorials, you'll see how to modify the database when the data model changes, without deleting and re-creating it.

Criar um controlador e exibiçõesCreate a controller and views

Em seguida, você usará o mecanismo de scaffolding no Visual Studio para adicionar um controlador MVC e exibições que usam o EF para consultar e salvar dados.Next, you'll use the scaffolding engine in Visual Studio to add an MVC controller and views that will use EF to query and save data.

A criação automática de métodos de ação CRUD e exibições é conhecida como scaffolding.The automatic creation of CRUD action methods and views is known as scaffolding. O scaffolding difere da geração de código, em que o código gerado por scaffolding é um ponto de partida que você pode modificar de acordo com seus requisitos, enquanto que normalmente o código gerado não é modificado.Scaffolding differs from code generation in that the scaffolded code is a starting point that you can modify to suit your own requirements, whereas you typically don't modify generated code. Quando precisar personalizar o código gerado, use classes parciais ou regenere o código quando as coisas mudarem.When you need to customize generated code, you use partial classes or you regenerate the code when things change.

  • Clique com o botão direito do mouse na pasta Controladores no Gerenciador de Soluções e selecione Adicionar > Novo Item Gerado por Scaffolding.Right-click the Controllers folder in Solution Explorer and select Add > New Scaffolded Item.

Se a caixa de diálogo Adicionar Dependências do MVC for exibida:If the Add MVC Dependencies dialog appears:

  • Atualize o Visual Studio para a última versão.Update Visual Studio to the latest version. Versões do Visual Studio anteriores a 15.5 mostram essa caixa de diálogo.Visual Studio versions prior to 15.5 show this dialog.

  • Se não puder atualizar, selecione ADICIONAR e, em seguida, siga as etapas de adição do controlador novamente.If you can't update, select ADD, and then follow the add controller steps again.

  • Na caixa de diálogo Adicionar Scaffolding:In the Add Scaffold dialog box:

    • Selecione Controlador MVC com exibições, usando o Entity Framework.Select MVC controller with views, using Entity Framework.

    • Clique em Adicionar.Click Add.

  • Na caixa de diálogo Adicionar Controlador:In the Add Controller dialog box:

    • Na classe Model, selecione Aluno.In Model class select Student.

    • Na Classe de contexto de dados selecione SchoolContext.In Data context class select SchoolContext.

    • Aceite o StudentsController padrão como o nome.Accept the default StudentsController as the name.

    • Clique em Adicionar.Click Add.

    Gerar aluno por scaffolding

    Quando você clica em Adicionar, o mecanismo de scaffolding do Visual Studio cria um arquivo StudentsController.cs e um conjunto de exibições (arquivos .cshtml) que funcionam com o controlador.When you click Add, the Visual Studio scaffolding engine creates a StudentsController.cs file and a set of views (.cshtml files) that work with the controller.

(O mecanismo de scaffolding também poderá criar o contexto de banco de dados para você se não criá-lo manualmente primeiro como fez anteriormente para este tutorial.(The scaffolding engine can also create the database context for you if you don't create it manually first as you did earlier for this tutorial. Especifique uma nova classe de contexto na caixa Adicionar Controlador clicando no sinal de adição à direita de Classe de contexto de dados.You can specify a new context class in the Add Controller box by clicking the plus sign to the right of Data context class. Em seguida, o Visual Studio criará a classe DbContext, bem como o controlador e as exibições.)Visual Studio will then create your DbContext class as well as the controller and views.)

Você observará que o controlador usa um SchoolContext como parâmetro de construtor.You'll notice that the controller takes a SchoolContext as a constructor parameter.

namespace ContosoUniversity.Controllers
{
    public class StudentsController : Controller
    {
        private readonly SchoolContext _context;

        public StudentsController(SchoolContext context)
        {
            _context = context;
        }

A injeção de dependência do ASP.NET Core é responsável por passar uma instância de SchoolContext para o controlador.ASP.NET Core dependency injection takes care of passing an instance of SchoolContext into the controller. Você configurou isso no arquivo Startup.cs anteriormente.You configured that in the Startup.cs file earlier.

O controlador contém um método de ação Index, que exibe todos os alunos no banco de dados.The controller contains an Index action method, which displays all students in the database. O método obtém uma lista de alunos do conjunto de entidades Students pela leitura da propriedade Students da instância de contexto de banco de dados:The method gets a list of students from the Students entity set by reading the Students property of the database context instance:

public async Task<IActionResult> Index()
{
    return View(await _context.Students.ToListAsync());
}

Você aprenderá sobre os elementos de programação assíncronos nesse código mais adiante no tutorial.You'll learn about the asynchronous programming elements in this code later in the tutorial.

A exibição Views/Students/Index.cshtml mostra esta lista em uma tabela:The Views/Students/Index.cshtml view displays this list in a table:

@model IEnumerable<ContosoUniversity.Models.Student>

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
                <th>
                    @Html.DisplayNameFor(model => model.LastName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.FirstMidName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.EnrollmentDate)
                </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.ID">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Pressione CTRL+F5 para executar o projeto ou escolha Depurar > Iniciar sem Depuração no menu.Press CTRL+F5 to run the project or choose Debug > Start Without Debugging from the menu.

Clique na guia Alunos para ver os dados de teste inserido pelo método DbInitializer.Initialize.Click the Students tab to see the test data that the DbInitializer.Initialize method inserted. Dependendo da largura da janela do navegador, você verá o link da guia Student na parte superior da página ou precisará clicar no ícone de navegação no canto superior direito para ver o link.Depending on how narrow your browser window is, you'll see the Student tab link at the top of the page or you'll have to click the navigation icon in the upper right corner to see the link.

Home page estreita da Contoso University

Página Índice de Alunos

Exibir o banco de dadosView the Database

Quando você iniciou o aplicativo, o método DbInitializer.Initialize chamou EnsureCreated.When you started the application, the DbInitializer.Initialize method calls EnsureCreated. O EF observou que não havia nenhum banco de dados e, portanto, ele criou um; em seguida, o restante do código do método Initialize populou o banco de dados com os dados.EF saw that there was no database and so it created one, then the remainder of the Initialize method code populated the database with data. Use o SSOX (Pesquisador de Objetos do SQL Server) para exibir o banco de dados no Visual Studio.You can use SQL Server Object Explorer (SSOX) to view the database in Visual Studio.

Feche o navegador.Close the browser.

Se a janela do SSOX ainda não estiver aberta, selecione-a no menu Exibir do Visual Studio.If the SSOX window isn't already open, select it from the View menu in Visual Studio.

No SSOX, clique em (localdb)\MSSQLLocalDB > Bancos de Dados e, em seguida, clique na entrada do nome do banco de dados que está na cadeia de conexão no arquivo appsettings.json.In SSOX, click (localdb)\MSSQLLocalDB > Databases, and then click the entry for the database name that's in the connection string in your appsettings.json file.

Expanda o nó Tabelas para ver as tabelas no banco de dados.Expand the Tables node to see the tables in your database.

Tabelas no SSOX

Clique com o botão direito do mouse na tabela Aluno e clique em Exibir Dados para ver as colunas criadas e as linhas que foram inseridas na tabela.Right-click the Student table and click View Data to see the columns that were created and the rows that were inserted into the table.

Tabela Aluno no SSOX

Os arquivos de banco de dados .mdf e .ldf estão na pasta C:\Users\.The .mdf and .ldf database files are in the C:\Users\ folder.

Como você está chamando EnsureCreated no método inicializador executado na inicialização do aplicativo, agora você pode fazer uma alteração na classe Student, excluir o banco de dados, executar novamente o aplicativo e o banco de dados será recriado automaticamente para que ele corresponda à alteração.Because you're calling EnsureCreated in the initializer method that runs on app start, you could now make a change to the Student class, delete the database, run the application again, and the database would automatically be re-created to match your change. Por exemplo, se você adicionar uma propriedade EmailAddress à classe Student, verá uma nova coluna EmailAddress na tabela recriada.For example, if you add an EmailAddress property to the Student class, you'll see a new EmailAddress column in the re-created table.

ConvençõesConventions

A quantidade de código feita para que o Entity Framework possa criar um banco de dados completo para você é mínima, devido ao uso de convenções ou de suposições feitas pelo Entity Framework.The amount of code you had to write in order for the Entity Framework to be able to create a complete database for you is minimal because of the use of conventions, or assumptions that the Entity Framework makes.

  • Os nomes de propriedades DbSet são usadas como nomes de tabela.The names of DbSet properties are used as table names. Para entidades não referenciadas por uma propriedade DbSet, os nomes de classe de entidade são usados como nomes de tabela.For entities not referenced by a DbSet property, entity class names are used as table names.

  • Os nomes de propriedade de entidade são usados para nomes de coluna.Entity property names are used for column names.

  • As propriedades de entidade que são nomeadas ID ou classnameID são reconhecidas como propriedades de chave primária.Entity properties that are named ID or classnameID are recognized as primary key properties.

  • Uma propriedade é interpretada como uma propriedade de chave estrangeira se ela é nomeada (por exemplo, StudentID para a propriedade de navegação Student, pois a chave primária da entidade Student é ID).A property is interpreted as a foreign key property if it's named (for example, StudentID for the Student navigation property since the Student entity's primary key is ID). As propriedades de chave estrangeira também podem ser nomeadas apenas (por exemplo, EnrollmentID, pois a chave primária da entidade Enrollment é EnrollmentID).Foreign key properties can also be named simply (for example, EnrollmentID since the Enrollment entity's primary key is EnrollmentID).

O comportamento convencional pode ser substituído.Conventional behavior can be overridden. Por exemplo, você pode especificar os nomes de tabela de forma explícita, conforme visto anteriormente neste tutorial.For example, you can explicitly specify table names, as you saw earlier in this tutorial. Além disso, você pode definir nomes de coluna e qualquer propriedade como a chave primária ou chave estrangeira, como você verá em um tutorial posterior desta série.And you can set column names and set any property as primary key or foreign key, as you'll see in a later tutorial in this series.

Código assíncronoAsynchronous code

A programação assíncrona é o modo padrão do ASP.NET Core e EF Core.Asynchronous programming is the default mode for ASP.NET Core and EF Core.

Um servidor Web tem um número limitado de threads disponíveis e, em situações de alta carga, todos os threads disponíveis podem estar em uso.A web server has a limited number of threads available, and in high load situations all of the available threads might be in use. Quando isso acontece, o servidor não pode processar novas solicitações até que os threads são liberados.When that happens, the server can't process new requests until the threads are freed up. Com um código síncrono, muitos threads podem ser vinculados enquanto realmente não são fazendo nenhum trabalho porque estão aguardando a conclusão da E/S.With synchronous code, many threads may be tied up while they aren't actually doing any work because they're waiting for I/O to complete. Com um código assíncrono, quando um processo está aguardando a conclusão da E/S, seu thread é liberado para o servidor para ser usado para processar outras solicitações.With asynchronous code, when a process is waiting for I/O to complete, its thread is freed up for the server to use for processing other requests. Como resultado, o código assíncrono permite que os recursos do servidor sejam usados com mais eficiência, e o servidor fica capacitado a manipular mais tráfego sem atrasos.As a result, asynchronous code enables server resources to be used more efficiently, and the server is enabled to handle more traffic without delays.

O código assíncrono introduz uma pequena quantidade de sobrecarga em tempo de execução, mas para situações de baixo tráfego, o impacto no desempenho é insignificante, ao passo que, em situações de alto tráfego, a melhoria de desempenho potencial é significativa.Asynchronous code does introduce a small amount of overhead at run time, but for low traffic situations the performance hit is negligible, while for high traffic situations, the potential performance improvement is substantial.

No código a seguir, a palavra-chave async, o valor retornado Task<T>, a palavra-chave await e o método ToListAsync fazem o código ser executado de forma assíncrona.In the following code, the async keyword, Task<T> return value, await keyword, and ToListAsync method make the code execute asynchronously.

public async Task<IActionResult> Index()
{
    return View(await _context.Students.ToListAsync());
}
  • A palavra-chave async instrui o compilador a gerar retornos de chamada para partes do corpo do método e a criar automaticamente o objeto Task<IActionResult> que é retornado.The async keyword tells the compiler to generate callbacks for parts of the method body and to automatically create the Task<IActionResult> object that's returned.

  • O tipo de retorno Task<IActionResult> representa um trabalho em andamento com um resultado do tipo IActionResult.The return type Task<IActionResult> represents ongoing work with a result of type IActionResult.

  • A palavra-chave await faz com que o compilador divida o método em duas partes.The await keyword causes the compiler to split the method into two parts. A primeira parte termina com a operação que é iniciada de forma assíncrona.The first part ends with the operation that's started asynchronously. A segunda parte é colocada em um método de retorno de chamada que é chamado quando a operação é concluída.The second part is put into a callback method that's called when the operation completes.

  • ToListAsync é a versão assíncrona do método de extensão ToList.ToListAsync is the asynchronous version of the ToList extension method.

Algumas coisas a serem consideradas quando você estiver escrevendo um código assíncrono que usa o Entity Framework:Some things to be aware of when you are writing asynchronous code that uses the Entity Framework:

  • Somente instruções que fazem com que consultas ou comandos sejam enviados ao banco de dados são executadas de forma assíncrona.Only statements that cause queries or commands to be sent to the database are executed asynchronously. Isso inclui, por exemplo, ToListAsync, SingleOrDefaultAsync e SaveChangesAsync.That includes, for example, ToListAsync, SingleOrDefaultAsync, and SaveChangesAsync. Isso não inclui, por exemplo, instruções que apenas alteram um IQueryable, como var students = context.Students.Where(s => s.LastName == "Davolio").It doesn't include, for example, statements that just change an IQueryable, such as var students = context.Students.Where(s => s.LastName == "Davolio").

  • Um contexto do EF não é thread-safe: não tente realizar várias operações em paralelo.An EF context isn't thread safe: don't try to do multiple operations in parallel. Quando você chamar qualquer método assíncrono do EF, sempre use a palavra-chave await.When you call any async EF method, always use the await keyword.

  • Se desejar aproveitar os benefícios de desempenho do código assíncrono, verifique se os pacotes de biblioteca que você está usando (por exemplo, para paginação) também usam o código assíncrono se eles chamam métodos do Entity Framework que fazem com que consultas sejam enviadas ao banco de dados.If you want to take advantage of the performance benefits of async code, make sure that any library packages that you're using (such as for paging), also use async if they call any Entity Framework methods that cause queries to be sent to the database.

Para obter mais informações sobre a programação assíncrona no .NET, consulte Visão geral da programação assíncrona.For more information about asynchronous programming in .NET, see Async Overview.

ResumoSummary

Agora, você criou um aplicativo simples que usa o Entity Framework Core e o LocalDB do SQL Server Express para armazenar e exibir dados.You've now created a simple application that uses the Entity Framework Core and SQL Server Express LocalDB to store and display data. No tutorial a seguir, você aprenderá a executar operações CRUD (criar, ler, atualizar e excluir) básicas.In the following tutorial, you'll learn how to perform basic CRUD (create, read, update, delete) operations.