Adicionar um novo campo ao modelo de filme e à tabela (C#)

por Rick Anderson

Observação

Uma versão atualizada deste tutorial está disponível aqui que usa ASP.NET MVC 5 e Visual Studio 2013. É mais seguro, muito mais simples de seguir e demonstra mais recursos.

Este tutorial ensinará os conceitos básicos da criação de um aplicativo Web ASP.NET MVC usando o Microsoft Visual Web Developer 2010 Express Service Pack 1, que é uma versão gratuita do Microsoft Visual Studio. Antes de começar, verifique se você instalou os pré-requisitos listados abaixo. Você pode instalar todos eles clicando no seguinte link: Web Platform Installer. Como alternativa, você pode instalar individualmente os pré-requisitos usando os seguintes links:

Se você estiver usando o Visual Studio 2010 em vez do Visual Web Developer 2010, instale os pré-requisitos clicando no seguinte link: Pré-requisitos do Visual Studio 2010.

Um projeto do Visual Web Developer com código-fonte C# está disponível para acompanhar este tópico. Baixe a versão do C#. Se preferir o Visual Basic, alterne para a versão do Visual Basic deste tutorial.

Nesta seção, você fará algumas alterações nas classes de modelo e aprenderá a atualizar o esquema de banco de dados para corresponder às alterações de modelo.

Adicionando uma propriedade de classificação ao modelo de filme

Comece adicionando uma nova Rating propriedade à classe existente Movie . Abra o arquivo Movie.cs e adicione a Rating propriedade como esta:

public string Rating { get; set; }

A classe completa Movie agora se parece com o seguinte código:

public class Movie
{
    public int      ID          { get; set; }
    public string   Title       { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string   Genre       { get; set; }
    public decimal  Price       { get; set; }
    public string   Rating      { get; set; }
}

Recompile o aplicativo usando o comando de menu Depurar>Build Movie .

Agora que você atualizou a Model classe, também precisa atualizar os modelos de exibição \Views\Movies\Index.cshtml e \Views\Movies\Create.cshtml para dar suporte à nova Rating propriedade.

Abra o arquivo \Views\Movies\Index.cshtml e adicione um <th>Rating</th> título de coluna logo após a coluna Preço . Em seguida, adicione uma <td> coluna perto do final do modelo para renderizar o @item.Rating valor. Veja abaixo a aparência do modelo de exibição Index.cshtml atualizado:

<table>
    <tr>
        <th></th>
        <th>Title</th>
        <th>Release Date</th>
        <th>Genre</th>
        <th>Price</th>
        <th>Rating</th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Rating   )
        </td>
        <td>
            @Html.ActionLink("Edit Me", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID })
        </td>
    </tr>
}
</table>

Em seguida, abra o arquivo \Views\Movies\Create.cshtml e adicione a marcação a seguir perto do final do formulário. Isso renderiza uma caixa de texto para que você possa especificar uma classificação quando um novo filme for criado.

<div class="editor-label">
    @Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Rating)
    @Html.ValidationMessageFor(model => model.Rating)
</div>

Gerenciando diferenças de esquema de modelo e banco de dados

Agora você atualizou o código do aplicativo para dar suporte à nova Rating propriedade.

Agora, execute o aplicativo e navegue até a URL /Movies . No entanto, ao fazer isso, você verá o seguinte erro:

Captura de tela que mostra a janela do navegador com um erro que declara Erro do Servidor no Aplicativo.

Você está vendo esse erro porque a classe de modelo atualizada Movie no aplicativo agora é diferente do esquema da Movie tabela do banco de dados existente. (Não há nenhuma coluna Rating na tabela de banco de dados.)

Por padrão, quando você usa o Entity Framework Code First para criar automaticamente um banco de dados, como fez anteriormente neste tutorial, o Code First adiciona uma tabela ao banco de dados para ajudar a controlar se o esquema do banco de dados está em sincronia com as classes de modelo das quais ele foi gerado. Se eles não estiverem sincronizados, o Entity Framework gerará um erro. Isso facilita o rastreamento de problemas no momento do desenvolvimento que, de outra forma, você só pode encontrar (por erros obscuros) em tempo de execução. O recurso de verificação de sincronização é o que faz com que a mensagem de erro seja exibida que você acabou de ver.

Há duas abordagens para resolver o erro:

  1. Faça com que o Entity Framework remova automaticamente e recrie o banco de dados com base no novo esquema de classe de modelo. Essa abordagem é muito conveniente ao fazer o desenvolvimento ativo em um banco de dados de teste, pois permite que você desenvolva rapidamente o modelo e o esquema de banco de dados juntos. A desvantagem, porém, é que você perde dados existentes no banco de dados, portanto, não deseja usar essa abordagem em um banco de dados de produção!
  2. Modifique explicitamente o esquema do banco de dados existente para que ele corresponda às classes de modelo. A vantagem dessa abordagem é que você mantém os dados. Faça essa alteração manualmente ou criando um script de alteração de banco de dados.

Para este tutorial, usaremos a primeira abordagem: você terá o Entity Framework Code First recriando automaticamente o banco de dados sempre que o modelo for alterado.

Re-Creating automaticamente o banco de dados em alterações de modelo

Vamos atualizar o aplicativo para que o Code First remova e recomece automaticamente o banco de dados sempre que você alterar o modelo para o aplicativo.

Observação

Aviso Você deve habilitar essa abordagem de descartar e recriar automaticamente o banco de dados somente quando estiver usando um banco de dados de desenvolvimento ou teste e nunca em um banco de dados de produção que contenha dados reais. Usá-lo em um servidor de produção pode levar à perda de dados.

Em Gerenciador de Soluções, clique com o botão direito do mouse na pasta Modelos, selecione Adicionar e, em seguida, selecione Classe.

Captura de tela que mostra a janela Gerenciador de Soluções. Adicionar está selecionado no menu Modelos com o botão direito do mouse. A classe é selecionada no submenu.

Nomeie a classe "MovieInitializer". Atualize a MovieInitializer classe para conter o seguinte código:

using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace MvcMovie.Models {
    public class MovieInitializer : DropCreateDatabaseIfModelChanges<MovieDBContext> {
        protected override void Seed(MovieDBContext context) {
            var movies = new List<Movie> {  
  
                 new Movie { Title = "When Harry Met Sally",   
                             ReleaseDate=DateTime.Parse("1989-1-11"),   
                             Genre="Romantic Comedy",  
                             Rating="R",  
                             Price=7.99M},  

                     new Movie { Title = "Ghostbusters ",   
                             ReleaseDate=DateTime.Parse("1984-3-13"),   
                             Genre="Comedy",  
                              Rating="R",  
                             Price=8.99M},   
  
                 new Movie { Title = "Ghostbusters 2",   
                             ReleaseDate=DateTime.Parse("1986-2-23"),   
                             Genre="Comedy",  
                             Rating="R",  
                             Price=9.99M},   

               new Movie { Title = "Rio Bravo",   
                             ReleaseDate=DateTime.Parse("1959-4-15"),   
                             Genre="Western",  
                             Rating="R",  
                             Price=3.99M},   
             };

            movies.ForEach(d => context.Movies.Add(d));
        }
    }
}

A MovieInitializer classe especifica que o banco de dados usado pelo modelo deve ser descartado e recriado automaticamente se as classes de modelo forem alteradas. O código inclui um Seed método para especificar alguns dados padrão a serem adicionados automaticamente ao banco de dados sempre que ele for criado (ou recriado). Isso fornece uma maneira útil de preencher o banco de dados com alguns dados de exemplo, sem exigir que você o preencha manualmente sempre que fizer uma alteração de modelo.

Agora que você definiu a MovieInitializer classe , convém conectá-la para que, sempre que o aplicativo for executado, ele verifique se as classes de modelo são diferentes do esquema no banco de dados. Se estiverem, você poderá executar o inicializador para recriar o banco de dados para corresponder ao modelo e, em seguida, preencher o banco de dados com os dados de exemplo.

Abra o arquivo Global.asax que está na raiz do MvcMovies projeto:

Captura de tela que mostra a guia Global dot asax dot c s. O ponto global asax é circulado em vermelho na janela Gerenciador de Soluções.

O arquivo Global.asax contém a classe que define todo o aplicativo para o projeto e contém um Application_Start manipulador de eventos que é executado quando o aplicativo é iniciado pela primeira vez.

Vamos adicionar duas instruções using à parte superior do arquivo. O primeiro faz referência ao namespace do Entity Framework e o segundo faz referência ao namespace em que reside nossa MovieInitializer classe:

using System.Data.Entity;            // Database.SetInitialize
using MvcMovie.Models;              // MovieInitializer

Em seguida, localize o Application_Start método e adicione uma chamada a Database.SetInitializer no início do método , conforme mostrado abaixo:

protected void Application_Start()
{
    Database.SetInitializer<MovieDBContext>(new MovieInitializer());

    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

A Database.SetInitializer instrução que você acabou de adicionar indica que o banco de dados usado pela MovieDBContext instância deve ser excluído e recriado automaticamente se o esquema e o banco de dados não corresponderem. E, como você viu, ele também preencherá o banco de dados com os dados de exemplo especificados na MovieInitializer classe .

Feche o arquivo Global.asax .

Execute novamente o aplicativo e navegue até a URL /Movies . Quando o aplicativo é iniciado, ele detecta que a estrutura do modelo não corresponde mais ao esquema de banco de dados. Ele recria automaticamente o banco de dados para corresponder à nova estrutura de modelo e preenche o banco de dados com os filmes de exemplo:

7_MyMovieList_SM

Clique no link Criar Novo para adicionar um novo filme. Observe que você pode adicionar uma classificação.

7_CreateRioII

Clique em Criar. O novo filme, incluindo a classificação, agora aparece na lista de filmes:

7_ourNewMovie_SM

Nesta seção, você viu como pode modificar objetos de modelo e manter o banco de dados sincronizado com as alterações. Você também aprendeu uma maneira de preencher um banco de dados recém-criado com dados de exemplo para poder experimentar cenários. Em seguida, vamos examinar como você pode adicionar uma lógica de validação mais avançada às classes de modelo e permitir que algumas regras de negócios sejam impostas.