Compartilhar via


Tutorial: Saiba mais sobre cenários avançados de EF para um aplicativo Web MVC 5

No tutorial anterior, você implementou a herança de tabela por hierarquia. Este tutorial inclui apresenta vários tópicos que são úteis para estar ciente quando você vai além dos conceitos básicos do desenvolvimento ASP.NET aplicativos Web que usam o Entity Framework Code First. As primeiras seções têm instruções passo a passo que orientam você pelo código e usando o Visual Studio para concluir tarefas As seções a seguir apresentam vários tópicos com breves introduçãos seguidas de links para recursos para obter mais informações.

Para a maioria desses tópicos, você trabalhará com páginas que já criou. Para usar o SQL bruto para fazer atualizações em massa, você criará uma nova página que atualiza o número de créditos de todos os cursos no banco de dados:

Update_Course_Credits_initial_page

Neste tutorial, você:

  • Executar consultas SQL brutas
  • Executar consultas sem acompanhamento
  • Examinar as consultas SQL enviadas ao banco de dados

Você também aprenderá sobre:

  • Criando uma camada de abstração
  • Classes de proxy
  • Detecção automática de alterações
  • Validação automática
  • Entity Framework Power Tools
  • Código-fonte do Entity Framework

Pré-requisito

Executar consultas SQL brutas

A API Entity Framework Code First inclui métodos que permitem passar comandos SQL diretamente para o banco de dados. Você tem as seguintes opções:

  • Use o método DbSet.SqlQuery para consultas que retornam tipos de entidade. Os objetos retornados devem ser do tipo esperado pelo DbSet objeto e são rastreados automaticamente pelo contexto do banco de dados, a menos que você desative o rastreamento. (Consulte a seção a seguir sobre o método AsNoTracking .)
  • Use o método Database.SqlQuery para consultas que retornam tipos que não são entidades. Os dados retornados não são controlados pelo contexto de banco de dados, mesmo se esse método é usado para recuperar tipos de entidade.
  • Use Database.ExecuteSqlCommand para comandos que não são de consulta.

Uma das vantagens de usar o Entity Framework é que ele evita vincular o código de forma muito próxima a um método específico de armazenamento de dados. Ele faz isso pela geração de consultas SQL e comandos para você, que também libera você da necessidade de escrevê-los. Mas há cenários excepcionais quando você precisa executar consultas SQL específicas que você criou manualmente e esses métodos possibilitam que você lide com essas exceções.

Como é sempre verdadeiro quando você executa comandos SQL em um aplicativo Web, é necessário tomar precauções para proteger o site contra ataques de injeção de SQL. Uma maneira de fazer isso é usar consultas parametrizadas para garantir que as cadeias de caracteres enviadas por uma página da Web não possam ser interpretadas como comandos SQL. Neste tutorial, você usará consultas parametrizadas ao integrar a entrada do usuário a uma consulta.

Chamando uma consulta que retorna entidades

A classe DbSet<TEntity> fornece um método que você pode usar para executar uma consulta que retorna uma entidade do tipo TEntity. Para ver como isso funciona, você alterará o código no Details método do Department controlador.

Em DepartmentController.cs, no Details método , substitua a chamada de db.Departments.FindAsync método por uma db.Departments.SqlQuery chamada de método, conforme mostrado no seguinte código realçado:

public async Task<ActionResult> Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    // Commenting out original code to show how to use a raw SQL query.
    //Department department = await db.Departments.FindAsync(id);

    // Create and execute raw SQL query.
    string query = "SELECT * FROM Department WHERE DepartmentID = @p0";
    Department department = await db.Departments.SqlQuery(query, id).SingleOrDefaultAsync();
    
    if (department == null)
    {
        return HttpNotFound();
    }
    return View(department);
}

Para verificar se o novo código funciona corretamente, selecione a guia Departamentos e, em seguida, Detalhes de um dos departamentos. Verifique se todos os dados são exibidos conforme o esperado.

Chamando uma consulta que retorna outros tipos de objetos

Anteriormente, você criou uma grade de estatísticas de alunos para a página Sobre que mostrava o número de alunos para cada data de registro. O código que faz isso em HomeController.cs usa LINQ:

var data = from student in db.Students
           group student by student.EnrollmentDate into dateGroup
           select new EnrollmentDateGroup()
           {
               EnrollmentDate = dateGroup.Key,
               StudentCount = dateGroup.Count()
           };

Suponha que você queira escrever o código que recupera esses dados diretamente no SQL em vez de usar LINQ. Para fazer isso, você precisa executar uma consulta que retorna algo diferente de objetos de entidade, o que significa que você precisa usar o método Database.SqlQuery .

Em HomeController.cs, substitua a instrução LINQ no About método por uma instrução SQL, conforme mostrado no seguinte código realçado:

public ActionResult About()
{
    // Commenting out LINQ to show how to do the same thing in SQL.
    //IQueryable<EnrollmentDateGroup> = from student in db.Students
    //           group student by student.EnrollmentDate into dateGroup
    //           select new EnrollmentDateGroup()
    //           {
    //               EnrollmentDate = dateGroup.Key,
    //               StudentCount = dateGroup.Count()
    //           };

    // SQL version of the above LINQ code.
    string query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
        + "FROM Person "
        + "WHERE Discriminator = 'Student' "
        + "GROUP BY EnrollmentDate";
    IEnumerable<EnrollmentDateGroup> data = db.Database.SqlQuery<EnrollmentDateGroup>(query);

    return View(data.ToList());
}

Execute a página Sobre. Verifique se ele exibe os mesmos dados que antes.

Chamando uma consulta de atualização

Suponha que os administradores da Contoso University queiram realizar alterações em massa no banco de dados, como alterar o número de créditos para cada curso. Se a universidade tiver uma grande quantidade de cursos, poderá ser ineficiente recuperá-los como entidades e alterá-los individualmente. Nesta seção, você implementará uma página da Web que permite que o usuário especifique um fator para alterar o número de créditos para todos os cursos e fará a alteração executando uma instrução SQL UPDATE .

Em CourseController.cs, adicione UpdateCourseCredits métodos para HttpGet e HttpPost:

public ActionResult UpdateCourseCredits()
{
    return View();
}

[HttpPost]
public ActionResult UpdateCourseCredits(int? multiplier)
{
    if (multiplier != null)
    {
        ViewBag.RowsAffected = db.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
    }
    return View();
}

Quando o controlador processa uma solicitação HttpGet , nada é retornado na ViewBag.RowsAffected variável e o modo de exibição exibe uma caixa de texto vazia e um botão enviar.

Quando o botão Atualizar é clicado, o HttpPost método é chamado e multiplier tem o valor inserido na caixa de texto. Em seguida, o código executa o SQL que atualiza cursos e retorna o número de linhas afetadas para a exibição na ViewBag.RowsAffected variável . Quando a exibição obtém um valor nessa variável, ela exibe o número de linhas atualizadas em vez da caixa de texto e o botão Enviar.

Em CourseController.cs, clique com o botão direito do mouse em um dos UpdateCourseCredits métodos e clique em Adicionar Exibição. A caixa de diálogo Adicionar Exibição é exibida. Deixe os padrões e selecione Adicionar.

Em Views\Course\UpdateCourseCredits.cshtml, substitua o código do modelo pelo seguinte código:

@model ContosoUniversity.Models.Course

@{
    ViewBag.Title = "UpdateCourseCredits";
}

<h2>Update Course Credits</h2>

@if (ViewBag.RowsAffected == null)
{
    using (Html.BeginForm())
    {
        <p>
            Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
        </p>
        <p>
            <input type="submit" value="Update" />
        </p>
    }
}
@if (ViewBag.RowsAffected != null)
{
    <p>
        Number of rows updated: @ViewBag.RowsAffected
    </p>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Execute o método UpdateCourseCredits selecionando a guia Cursos, adicionando, em seguida, "/UpdateCourseCredits" ao final da URL na barra de endereços do navegador (por exemplo: http://localhost:50205/Course/UpdateCourseCredits). Insira um número na caixa de texto:

Update_Course_Credits_initial_page_with_2_entered

Clique em Atualizar. Você verá o número de linhas afetadas.

Clique em Voltar para a Lista para ver a lista de cursos com o número revisado de créditos.

Para obter mais informações sobre consultas SQL brutas, consulte Consultas SQL brutas no MSDN.

Consultas sem controle

Quando um contexto de banco de dados recupera linhas de tabela e cria objetos de entidade que as representam, por padrão, ele controla se as entidades em memória estão em sincronia com o que está no banco de dados. Os dados em memória atuam como um cache e são usados quando uma entidade é atualizada. Esse cache costuma ser desnecessário em um aplicativo Web porque as instâncias de contexto são normalmente de curta duração (uma nova é criada e descartada para cada solicitação) e o contexto que lê uma entidade normalmente é descartado antes que essa entidade seja usada novamente.

Você pode desabilitar o acompanhamento de objetos de entidade na memória usando o método AsNoTracking . Os cenários típicos em que talvez você deseje fazer isso incluem os seguintes:

  • Uma consulta recupera um volume tão grande de dados que desativar o controle pode melhorar visivelmente o desempenho.
  • Você deseja anexar uma entidade para atualizá-la, mas você recuperou anteriormente a mesma entidade para uma finalidade diferente. Como a entidade já está sendo controlada pelo contexto de banco de dados, não é possível anexar a entidade que você deseja alterar. Uma maneira de lidar com essa situação é usar a opção AsNoTracking com a consulta anterior.

Para obter um exemplo que demonstra como usar o método AsNoTracking , consulte a versão anterior deste tutorial. Esta versão do tutorial não define o sinalizador Modificado em uma entidade criada pelo model-binder no método Edit, portanto, não precisa AsNoTrackingde .

Examinar o SQL enviado ao banco de dados

Às vezes, é útil poder ver as consultas SQL reais que são enviadas ao banco de dados. Em um tutorial anterior, você viu como fazer isso no código do interceptador; agora você verá algumas maneiras de fazer isso sem escrever código interceptador. Para experimentar isso, você examinará uma consulta simples e examinará o que acontece com ela à medida que adiciona opções como carregamento adiantado, filtragem e classificação.

Em Controllers/CourseController, substitua o Index método pelo seguinte código, a fim de interromper temporariamente o carregamento adiantado:

public ActionResult Index()
{
    var courses = db.Courses;
    var sql = courses.ToString();
    return View(courses.ToList());
}

Agora, defina um ponto de interrupção na return instrução (F9 com o cursor nessa linha). Pressione F5 para executar o projeto no modo de depuração e selecione a página Índice do Curso. Quando o código atingir o ponto de interrupção, examine a sql variável . Você verá a consulta enviada para SQL Server. É uma instrução simples Select .

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}

Clique na lupa para ver a consulta no Visualizador de Texto.

Uma captura de tela que mostra o Controlador de Curso com uma linha de código realçada. Outra captura de tela que mostra o Visualizador de Texto aberto e uma lupa é circulada em vermelho no campo Valor.

Agora você adicionará uma lista suspensa à página Índice de Cursos para que os usuários possam filtrar um departamento específico. Você classificará os cursos por título e especificará o carregamento adiantado para a Department propriedade de navegação.

Em CourseController.cs, substitua o Index método pelo seguinte código:

public ActionResult Index(int? SelectedDepartment)
{
    var departments = db.Departments.OrderBy(q => q.Name).ToList();
    ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);
    int departmentID = SelectedDepartment.GetValueOrDefault();

    IQueryable<Course> courses = db.Courses
        .Where(c => !SelectedDepartment.HasValue || c.DepartmentID == departmentID)
        .OrderBy(d => d.CourseID)
        .Include(d => d.Department);
    var sql = courses.ToString();
    return View(courses.ToList());
}

Restaure o ponto de interrupção na instrução return .

O método recebe o valor selecionado da lista suspensa no SelectedDepartment parâmetro . Se nada for selecionado, esse parâmetro será nulo.

Uma SelectList coleção que contém todos os departamentos é passada para a exibição da lista suspensa. Os parâmetros passados para o SelectList construtor especificam o nome do campo de valor, o nome do campo de texto e o item selecionado.

Para o Get método do Course repositório, o código especifica uma expressão de filtro, uma ordem de classificação e carregamento ansioso para a Department propriedade de navegação. A expressão de filtro sempre retornará true se nada for selecionado na lista suspensa (ou seja, SelectedDepartment é nula).

Em Views\Course\Index.cshtml, imediatamente antes da marca de abertura table , adicione o seguinte código para criar a lista suspensa e um botão enviar:

@using (Html.BeginForm())
{
    <p>Select Department: @Html.DropDownList("SelectedDepartment","All")   
    <input type="submit" value="Filter" /></p>
}

Com o ponto de interrupção ainda definido, execute a página Índice do Curso. Continue nas primeiras vezes em que o código atinge um ponto de interrupção, para que a página seja exibida no navegador. Selecione um departamento na lista suspensa e clique em Filtrar.

Desta vez, o primeiro ponto de interrupção será para a consulta de departamentos para a lista suspensa. Ignore isso e exiba a query variável na próxima vez que o código atingir o ponto de interrupção para ver a aparência da Course consulta agora. Você verá algo semelhante ao seguinte:

SELECT 
    [Project1].[CourseID] AS [CourseID], 
    [Project1].[Title] AS [Title], 
    [Project1].[Credits] AS [Credits], 
    [Project1].[DepartmentID] AS [DepartmentID], 
    [Project1].[DepartmentID1] AS [DepartmentID1], 
    [Project1].[Name] AS [Name], 
    [Project1].[Budget] AS [Budget], 
    [Project1].[StartDate] AS [StartDate], 
    [Project1].[InstructorID] AS [InstructorID], 
    [Project1].[RowVersion] AS [RowVersion]
    FROM ( SELECT 
        [Extent1].[CourseID] AS [CourseID], 
        [Extent1].[Title] AS [Title], 
        [Extent1].[Credits] AS [Credits], 
        [Extent1].[DepartmentID] AS [DepartmentID], 
        [Extent2].[DepartmentID] AS [DepartmentID1], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[Budget] AS [Budget], 
        [Extent2].[StartDate] AS [StartDate], 
        [Extent2].[InstructorID] AS [InstructorID], 
        [Extent2].[RowVersion] AS [RowVersion]
        FROM  [dbo].[Course] AS [Extent1]
        INNER JOIN [dbo].[Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
        WHERE @p__linq__0 IS NULL OR [Extent1].[DepartmentID] = @p__linq__1
    )  AS [Project1]
    ORDER BY [Project1].[CourseID] ASC

Você pode ver que a consulta agora é uma JOIN consulta que carrega Department dados junto com os Course dados e que ela inclui uma WHERE cláusula .

Remova a var sql = courses.ToString() linha.

Criar uma camada de abstração

Muitos desenvolvedores escrevem um código para implementar padrões de repositório e unidade de trabalho como um wrapper em torno do código que funciona com o Entity Framework. Esses padrões destinam-se a criar uma camada de abstração entre a camada de acesso a dados e a camada da lógica de negócios de um aplicativo. A implementação desses padrões pode ajudar a isolar o aplicativo de alterações no armazenamento de dados e pode facilitar o teste de unidade automatizado ou TDD (desenvolvimento orientado por testes). No entanto, escrever código adicional para implementar esses padrões nem sempre é a melhor opção para aplicativos que usam o EF, por vários motivos:

  • A própria classe de contexto do EF isola o código de código específico a um armazenamento de dados.
  • A classe de contexto do EF pode atuar como uma classe de unidade de trabalho para as atualizações de banco de dados feitas com o EF.
  • Os recursos introduzidos no Entity Framework 6 facilitam a implementação do TDD sem escrever código de repositório.

Para obter mais informações sobre como implementar o repositório e a unidade de padrões de trabalho, consulte a versão Entity Framework 5 desta série de tutoriais. Para obter informações sobre maneiras de implementar o TDD no Entity Framework 6, consulte os seguintes recursos:

Classes de proxy

Quando o Entity Framework cria instâncias de entidade (por exemplo, quando você executa uma consulta), ela geralmente as cria como instâncias de um tipo derivado gerado dinamicamente que atua como um proxy para a entidade. Por exemplo, confira as duas imagens de depurador a seguir. Na primeira imagem, você verá que a student variável é o tipo esperado Student imediatamente após instanciar a entidade. Na segunda imagem, após o EF ter sido usado para ler uma entidade de aluno do banco de dados, você verá a classe proxy.

Antes da classe proxy

Após a classe proxy

Essa classe proxy substitui algumas propriedades virtuais da entidade para inserir ganchos para executar ações automaticamente quando a propriedade é acessada. Uma função para a qual esse mecanismo é usado é o carregamento lento.

Na maioria das vezes, você não precisa estar ciente desse uso de proxies, mas há exceções:

  • Em alguns cenários, talvez você queira impedir que o Entity Framework crie instâncias de proxy. Por exemplo, quando você está serializando entidades, geralmente deseja as classes POCO, não as classes de proxy. Uma maneira de evitar problemas de serialização é serializar DTOs (objetos de transferência de dados) em vez de objetos de entidade, conforme mostrado no tutorial Usando a API Web com o Entity Framework . Outra maneira é desabilitar a criação de proxy.
  • Ao instanciar uma classe de entidade usando o new operador , você não obtém uma instância de proxy. Isso significa que você não obtém funcionalidades como carregamento lento e controle automático de alterações. Normalmente está tudo bem; você geralmente não precisa de carregamento lento, pois está criando uma nova entidade que não está no banco de dados e geralmente não precisa de controle de alterações se estiver marcando explicitamente a entidade como Added. No entanto, se você precisar de carregamento lento e precisar de controle de alterações, poderá criar novas instâncias de entidade com proxies usando o método Create da DbSet classe .
  • Talvez você queira obter um tipo de entidade real de um tipo de proxy. Você pode usar o método GetObjectType da ObjectContext classe para obter o tipo de entidade real de uma instância de tipo proxy.

Para obter mais informações, consulte Trabalhando com proxies no MSDN.

Detecção automática de alterações

O Entity Framework determina como uma entidade foi alterada (e, portanto, quais atualizações precisam ser enviadas ao banco de dados), comparando os valores atuais de uma entidade com os valores originais. Os valores originais são armazenados quando a entidade é consultada ou anexada. Alguns dos métodos que causam a detecção automática de alterações são os seguintes:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Remove
  • DbSet.Add
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Se você estiver acompanhando um grande número de entidades e chamar um desses métodos muitas vezes em um loop, poderá obter melhorias significativas de desempenho desativando temporariamente a detecção automática de alterações usando a propriedade AutoDetectChangesEnabled . Para obter mais informações, consulte Detectando automaticamente alterações no MSDN.

Validação automática

Quando você chama o SaveChanges método , por padrão, o Entity Framework valida os dados em todas as propriedades de todas as entidades alteradas antes de atualizar o banco de dados. Se você atualizou um grande número de entidades e já validou os dados, esse trabalho é desnecessário e você pode fazer com que o processo de salvar as alterações leve menos tempo desativando temporariamente a validação. Você pode fazer isso usando a propriedade ValidateOnSaveEnabled . Para obter mais informações, consulte Validação no MSDN.

Entity Framework Power Tools

O Entity Framework Power Tools é um suplemento do Visual Studio que foi usado para criar os diagramas de modelo de dados mostrados nestes tutoriais. As ferramentas também podem fazer outras funções, como gerar classes de entidade com base nas tabelas em um banco de dados existente para que você possa usar o banco de dados com o Code First. Depois de instalar as ferramentas, algumas opções adicionais aparecem nos menus de contexto. Por exemplo, quando você clica com o botão direito do mouse em sua classe de contexto em Gerenciador de Soluções, você vê e a opção Entity Framework. Isso oferece a capacidade de gerar um diagrama. Ao usar o Code First, você não pode alterar o modelo de dados no diagrama, mas pode mover as coisas para facilitar a compreensão.

Diagrama do EF

Código-fonte do Entity Framework

O código-fonte do Entity Framework 6 está disponível no GitHub. Você pode arquivar bugs e contribuir com seus próprios aprimoramentos para o código-fonte do EF.

Embora o código-fonte esteja aberto, o Entity Framework tem suporte total como um produto da Microsoft. A equipe do Microsoft Entity Framework mantém controle sobre quais contribuições são aceitas e testa todas as alterações de código para garantir a qualidade de cada versão.

Agradecimentos

  • Tom Dykstra escreveu a versão original deste tutorial, foi coautor da atualização do EF 5 e escreveu a atualização do EF 6. Tom é um escritor sênior de programação na Equipe de Conteúdo da Plataforma Web e Ferramentas da Microsoft.
  • Rick Anderson ( twitter @RickAndMSFT) fez a maior parte do trabalho atualizando o tutorial para EF 5 e MVC 4 e co-autor da atualização do EF 6. Rick é um escritor de programação sênior da Microsoft com foco no Azure e no MVC.
  • Rowan Miller e outros membros da equipe do Entity Framework ajudaram nas revisões de código e ajudaram a depurar muitos problemas com migrações que surgiram enquanto atualizamos o tutorial para o EF 5 e o EF 6.

Solucionar erros comuns

Não é possível criar/copiar sombra

Mensagem de erro:

Não é possível criar/sombrear a cópia '<filename>' quando esse arquivo já existir.

Solução

Aguarde alguns segundos e atualize a página.

Update-Database não reconhecido

Mensagem de erro (do Update-Database comando no PMC):

O termo 'Update-Database' não é reconhecido como o nome de um cmdlet, função, arquivo de script ou programa operável. Verifique a ortografia do nome ou se um caminho foi incluído, verifique se ele está correto e tente novamente.

Solução

Saia do Visual Studio. Reabra o projeto e tente novamente.

Falha na validação

Mensagem de erro (do Update-Database comando no PMC):

Falha na validação de uma ou mais entidades. Consulte a propriedade 'EntityValidationErrors' para obter mais detalhes.

Solução

Uma das causas desse problema são os erros de validação quando o Seed método é executado. Consulte Propagação e depuração de DBs do EF (Entity Framework) para obter dicas sobre como depurar o Seed método.

Erro HTTP 500.19

Mensagem de erro:

Erro HTTP 500.19 – Erro interno do servidor A página solicitada não pode ser acessada porque os dados de configuração relacionados para a página são inválidos.

Solução

Uma maneira de obter esse erro é por ter várias cópias da solução, cada uma delas usando o mesmo número de porta. Normalmente, você pode resolver esse problema saindo de todas as instâncias do Visual Studio e reiniciando o projeto no qual está trabalhando. Se isso não funcionar, tente alterar o número da porta. Clique com o botão direito do mouse no arquivo de projeto e clique em propriedades. Selecione a guia Web e altere o número da porta na caixa de texto URL do Projeto .

Erro ao localizar a instância do SQL Server

Mensagem de erro:

Ocorreu um erro relacionado à rede ou específico da instância ao estabelecer uma conexão com o SQL Server. O servidor não foi encontrado ou não estava acessível. Verifique se o nome de instância está correto e se o SQL Server está configurado para permitir conexões remotas. (provedor: Adaptadores de Rede do SQL, erro: 26 – Erro ao Localizar Servidor/Instância Especificada)

Solução

Verifique a cadeia de conexão. Se você tiver excluído manualmente o banco de dados, altere o nome do banco de dados na cadeia de caracteres de construção.

Obter o código

Baixar Projeto Concluído

Recursos adicionais

Para obter mais informações sobre como trabalhar com dados usando o Entity Framework, consulte a página de documentação do EF no MSDN e ASP.NET Acesso a Dados – Recursos Recomendados.

Para obter mais informações sobre como implantar seu aplicativo Web depois de compilá-lo, consulte ASP.NET Implantação da Web – Recursos Recomendados no Biblioteca MSDN.

Para obter informações sobre outros tópicos relacionados ao MVC, como autenticação e autorização, consulte o ASP.NET MVC – Recursos Recomendados.

Próximas etapas

Neste tutorial, você:

  • Executou consultas SQL brutas
  • Consultas sem acompanhamento executadas
  • Consultas SQL examinadas enviadas ao banco de dados

Você também aprendeu sobre:

  • Criando uma camada de abstração
  • Classes de proxy
  • Detecção automática de alterações
  • Validação automática
  • Entity Framework Power Tools
  • Código-fonte do Entity Framework

Isso conclui esta série de tutoriais sobre como usar o Entity Framework em um aplicativo ASP.NET MVC. Se você quiser saber mais sobre o Banco de Dados EF Primeiro, consulte a série de tutoriais Primeiro banco de dados.