Adicionar um novo campo ao modelo de filme e à tabela
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.
Nesta seção, você usará as Migrações do Code First do Entity Framework para migrar algumas alterações nas classes de modelo para que a alteração seja aplicada ao 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 tempo de desenvolvimento que, de outra forma, você só encontraria (por erros obscuros) em tempo de execução.
Configurando migrações do Code First para alterações de modelo
Se você estiver usando o Visual Studio 2012, clique duas vezes no arquivo Movies.mdf do Gerenciador de Soluções para abrir a ferramenta de banco de dados. O Visual Studio Express para Web mostrará o Gerenciador de Banco de Dados, o Visual Studio 2012 mostrará o Gerenciador de Servidores. Se você estiver usando o Visual Studio 2010, use o Pesquisador de Objetos do SQL Server.
Na ferramenta de banco de dados (Explorador de Banco de Dados, Gerenciador de Servidores ou Pesquisador de Objetos do SQL Server), clique com o botão direito do MovieDBContext
mouse e selecione Excluir para descartar o banco de dados de filmes.
Navegue de volta para o Gerenciador de Soluções. Clique com o botão direito do mouse no arquivo Movies.mdf e selecione Excluir para remover o banco de dados de filmes.
Compile o aplicativo para verificar se não existem erros.
No menu Ferramentas, clique em Gerenciador de Pacotes NuGet e, em seguida, em Console do Gerenciador de Pacotes.
Na janela Console do Gerenciador de Pacotes , no prompt, PM>
insira "Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext".
O comando Enable-Migrations (mostrado acima) cria um arquivo Configuration.cs em uma nova pasta Migrations .
O Visual Studio abre o arquivo Configuration.cs . Substitua o Seed
método no arquivo Configuration.cs pelo seguinte código:
protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
context.Movies.AddOrUpdate( i => i.Title,
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Price = 7.99M
},
new Movie
{
Title = "Ghostbusters ",
ReleaseDate = DateTime.Parse("1984-3-13"),
Genre = "Comedy",
Price = 8.99M
},
new Movie
{
Title = "Ghostbusters 2",
ReleaseDate = DateTime.Parse("1986-2-23"),
Genre = "Comedy",
Price = 9.99M
},
new Movie
{
Title = "Rio Bravo",
ReleaseDate = DateTime.Parse("1959-4-15"),
Genre = "Western",
Price = 3.99M
}
);
}
Clique com o botão direito do mouse na linha ondulada vermelha abaixo Movie
e selecione Resolver e usando MvcMovie.Models;
Isso adiciona a seguinte instrução using:
using MvcMovie.Models;
Observação
As Migrações do Code First chamam o Seed
método após cada migração (ou seja, chamando update-database no Console do Gerenciador de Pacotes) e esse método atualiza as linhas que já foram inseridas ou as insere se ainda não existirem.
Pressione CTRL-SHIFT-B para criar o projeto.(As etapas a seguir falharão se você não compilar neste momento.)
A próxima etapa é criar uma DbMigration
classe para a migração inicial. Essa migração para cria um novo banco de dados, é por isso que você excluiu o arquivo movie.mdf em uma etapa anterior.
Na janela Console do Gerenciador de Pacotes , insira o comando "add-migration Initial" para criar a migração inicial. O nome "Inicial" é arbitrário e é usado para nomear o arquivo de migração criado.
As Migrações do Code First criam outro arquivo de classe na pasta Migrações (com o nome {DateStamp}_Initial.cs ), e essa classe contém código que cria o esquema de banco de dados. O nome do arquivo de migração é previamente corrigido com um carimbo de data/hora para ajudar com a ordenação. Examine o arquivo {DateStamp}_Initial.cs , ele contém as instruções para criar a tabela Filmes para o banco de dados de filmes. Quando você atualiza o banco de dados nas instruções abaixo, esse arquivo {DateStamp}_Initial.cs é executado e cria o esquema de banco de dados. Em seguida, o método Seed será executado para preencher o banco de dados com dados de teste.
No Console do Gerenciador de Pacotes, insira o comando "update-database" para criar o banco de dados e executar o método Seed .
Se você receber um erro que indica que uma tabela já existe e não pode ser criada, provavelmente é porque você executou o aplicativo depois de excluir o banco de dados e antes de executar update-database
. Nesse caso, exclua o arquivo Movies.mdf novamente e tente novamente o update-database
comando. Se você ainda receber um erro, exclua a pasta de migrações e o conteúdo e comece com as instruções na parte superior desta página (ou seja, exclua o arquivo Movies.mdf e prossiga para Enable-Migrations).
Execute o aplicativo e navegue até a URL / Movies . Os dados de semente são exibidos.
Adicionando uma propriedade de classificação ao modelo de filme
Comece adicionando uma nova Rating
propriedade à classe existente Movie
. Abra o arquivo Models\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; }
}
Compile o aplicativo usando o comando de menu Build>Build Movie ou pressionando CTRL-SHIFT-B.
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 exibir a nova Rating
propriedade no modo de exibição do navegador.
Abra o arquivo \Views\Movies\Index.cshtml e adicione um título de <th>Rating</th>
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. Abaixo está a aparência do modelo de exibição Index.cshtml atualizado:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Rating)
</th>
<th></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", "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 é 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>
Agora você atualizou o código do aplicativo para dar suporte à nova Rating
propriedade.
Agora execute o aplicativo e navegue até o URL /Movies . Ao fazer isso, porém, você verá um dos seguintes erros:
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.)
Existem algumas abordagens para resolver o erro:
- 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; Ele permite que você evolua rapidamente o modelo e o esquema de banco de dados juntos. A desvantagem, porém, é que você perde os dados existentes no banco de dados — portanto, não deseja usar essa abordagem em um banco de dados de produção! Usar um inicializador para propagar automaticamente um banco de dados com dados de teste geralmente é uma maneira produtiva de desenvolver um aplicativo. Para obter mais informações sobre inicializadores de banco de dados do Entity Framework, consulte o tutorial ASP.NET MVC/Entity Framework de Tom Dykstra.
- 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.
- Use as Migrações do Code First para atualizar o esquema de banco de dados.
Para este tutorial, usaremos as Migrações do Code First.
Atualize o método Seed para que ele forneça um valor para a nova coluna. Abra o arquivo Migrations\Configuration.cs e adicione um campo Rating a cada objeto Movie.
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Rating = "G",
Price = 7.99M
},
Compile a solução e, em seguida, abra a janela Console do Gerenciador de Pacotes e insira o seguinte comando:
add-migration AddRatingMig
O add-migration
comando informa à estrutura de migração para examinar o modelo de filme atual com o esquema de banco de dados de filme atual e criar o código necessário para migrar o banco de dados para o novo modelo. O AddRatingMig é arbitrário e é usado para nomear o arquivo de migração. É útil usar um nome significativo para a etapa de migração.
Quando esse comando for concluído, o Visual Studio abrirá o arquivo de classe que define a nova DbMigration
classe derivada e, no Up
método, você poderá ver o código que cria a nova coluna.
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn("dbo.Movies", "Rating", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Movies", "Rating");
}
}
Compile a solução e insira o comando "update-database" na janela Console do Gerenciador de Pacotes .
A imagem a seguir mostra a saída na janela Console do Gerenciador de Pacotes (o carimbo de data anterior AddRatingMig será diferente.)
Execute novamente o aplicativo e navegue até a URL /Movies. Você pode ver o novo campo Classificação.
Clique no link Criar novo para adicionar um novo filme. Observe que você pode adicionar uma classificação.
Clique em Criar. O novo filme, incluindo a classificação, agora aparece na lista de filmes:
Você também deve adicionar o Rating
campo aos modelos de exibição Editar, Detalhes e SearchIndex.
Você pode inserir o comando "update-database" na janela do Console do Gerenciador de Pacotes novamente e nenhuma alteração será feita, pois o esquema corresponde ao modelo.
Nesta seção, você viu como modificar objetos de modelo e manter o banco de dados em sincronia com as alterações. Você também aprendeu uma maneira de preencher um banco de dados recém-criado com dados de exemplo para que possa experimentar cenários. Em seguida, vamos ver 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.