Agregar un nuevo campo a la tabla y modelo de películas
Nota:
Hay disponible aquí una versión actualizada de este tutorial que usa ASP.NET MVC 5 y Visual Studio 2013. Es más seguro, mucho más sencillo de seguir y muestra más características.
En esta sección usará Migraciones de Code First de Entity Framework para migrar algunos cambios a las clases de modelo para que el cambio se aplique a la base de datos.
De forma predeterminada, cuando se usa Entity Framework Code First para crear automáticamente una base de datos, como hizo anteriormente en este tutorial, Code First agrega una tabla a la base de datos para ayudar a realizar un seguimiento de si el esquema de la base de datos está sincronizado con las clases de modelo de las que se generó. Si no están sincronizados, Entity Framework produce un error. Esto facilita el seguimiento de problemas durante el desarrollo que, de lo contrario, solo encontraría (por errores ocultos) en tiempo de ejecución.
Configuración de migraciones de Code First para cambios de modelo
Si usa Visual Studio 2012, haga doble clic en el archivo Movies.mdf del Explorador de soluciones para abrir la herramienta de base de datos. Visual Studio Express para Web mostrará el Explorador de bases de datos, Visual Studio 2012 mostrará el Explorador de servidores. Si usa Visual Studio 2010, use el Explorador de objetos de SQL Server.
En la herramienta de base de datos (Explorador de bases de datos, Explorador de servidores o Explorador de objetos de SQL Server), haga clic con el botón derecho en MovieDBContext
y seleccione Eliminar para quitar la base de datos de películas.
Vuelva al Explorador de soluciones. Haga clic con el botón derecho en el archivo Movies.mdf y seleccione Eliminar para quitar la base de datos de películas.
Compile la aplicación para asegurarse de que no hay ningún error.
En el menú Tools (Herramientas), haga clic en Administrador de paquetes NuGet y luego en Consola del Administrador de paquetes.
En la ventana Consola del administrador de paquetes, en el indicador PM>
introduzca "Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext".
El comando Enable-Migrations (mostrado anteriormente) crea un archivo Configuration.cs en una nueva carpeta de Migraciones.
Visual Studio abre el archivo Configuration.cs. Reemplace el método Seed
en el archivo Configuration.cs por el código siguiente:
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
}
);
}
Haga clic con el botón derecho en la línea ondulada roja debajo de Movie
y seleccione Resolver y, a continuación, use MvcMovie.Models;
Al hacerlo, se agregan las siguientes instrucciones using:
using MvcMovie.Models;
Nota:
Migraciones de Code First llama al método Seed
después de cada migración (es decir, llama a update-database en la consola del Administrador de paquetes) y este método actualiza las filas que ya se han insertado o las inserta si aún no existen.
Presione CTRL-MAYÚS-B para compilar el proyecto (se producirá un error en los pasos siguientes si no se compila en este momento).
El siguiente paso es crear una clase DbMigration
para la migración inicial. Esta migración crea una nueva base de datos, es por ello que eliminó el archivo movie.mdf en un paso anterior.
En la ventana Consola del Administrador de paquetes, escriba el comando "add-migration Initial" para crear la migración inicial. El nombre "Initial" es arbitrario y se usa para asignar un nombre al archivo de migración.
Migraciones de Code First crea otro archivo de clase en la carpeta Migraciones (con el nombre {DateStamp}_Initial.cs) y esta clase contiene el código que crea el esquema de la base de datos. El nombre de archivo de la migración lleva una marca de tiempo para ayudar con el orden. Examine el archivo {DateStamp}_Initial.cs, contiene las instrucciones para crear la tabla Movies para Movie DB. Al actualizar la base de datos en las instrucciones siguientes, este archivo {DateStamp}_Initial.cs se ejecutará y creará el esquema de la base de datos. A continuación, el método Seed se ejecutará para rellenar la base de datos con datos de prueba.
En la Consola del Administrador de paquetes, escriba el comando "update-database" para crear la base de datos y ejecutar el método Seed.
Si recibe un error que indica que ya existe una tabla y no se puede crear, es probable que se deba a que ejecutó la aplicación después de eliminar la base de datos y antes de ejecutar update-database
. En ese caso, elimine de nuevo el archivo Movies.mdf y vuelva a intentarlo con el comando update-database
. Si sigue recibiendo un error, elimine la carpeta de migraciones y el contenido, comience con las instrucciones de la parte superior de esta página (es decir, elimine el archivo Movies.mdf y, a continuación, continúe con Enable-Migrations).
Ejecute la aplicación y navegue a la URL /Movies. Se muestran los datos de inicialización.
Adición de una propiedad de clasificación al modelo Movie
Para empezar, agregue una nueva propiedad Rating
a la clase Movie
existente. Abra el archivo Models\Movie.cs y agregue la propiedad Rating
como esta:
public string Rating { get; set; }
La clase Movie
completa ahora tiene el siguiente aspecto:
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; }
}
Construya la aplicación utilizando el comando de menú Compilar>Compilar película o pulsando CTRL-SHIFT-B.
Ahora que ha actualizado la clase Model
, también debe actualizar las plantillas de vista Views\Movies\Index.cshtml y Views\Movies\Create.cshtml para mostrar la nueva propiedad Rating
en la vista del navegador.
Abra el archivo \Views\Movies\Index.cshtml y agregue un encabezado de columna <th>Rating</th>
justo después de la columna Price. Después, agregue una columna <td>
cerca del final de la plantilla para representar el valor @item.Rating
. A continuación se muestra el aspecto de la plantilla de vista Index.cshtml actualizada:
@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>
A continuación, abra el archivo \Views\Movies\Create.cshtml y agregue el siguiente marcado cerca del final del formulario. Esto representa un cuadro de texto para que pueda especificar una clasificación cuando se crea una película.
<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>
Ahora ha actualizado el código de la aplicación para admitir la nueva propiedad Rating
.
Ejecute la aplicación y vaya a la dirección URL /Movies. Sin embargo, al hacerlo, verá uno de los siguientes errores:
Este error se muestra porque la clase del modelo Movie
actualizada en la aplicación es diferente del esquema de la tabla Movie
de la base de datos existente. (No hay ninguna columna Rating
en la tabla de la base de datos).
Este error se puede resolver de varias maneras:
- Haga que Entity Framework quite de forma automática la base de datos y la vuelva a crear basándose en el nuevo esquema de la clase del modelo. Este enfoque resulta muy conveniente cuando se realiza el desarrollo activo en una base de datos de prueba; permite desarrollar rápidamente el esquema del modelo y la base de datos de manera conjunta. La desventaja es que se pierden los datos existentes en la base de datos, así que no use este enfoque en una base de datos de producción. Usar un inicializador para inicializar automáticamente una base de datos con datos de prueba suele ser una manera productiva de desarrollar una aplicación. Para obtener más información sobre los inicializadores de base de datos de Entity Framework, consulte el tutorial ASP.NET MVC/Entity Framework de Tom Dykstra.
- Modifique explícitamente el esquema de la base de datos existente para que coincida con las clases del modelo. La ventaja de este enfoque es que se conservan los datos. Puede realizar este cambio de forma manual o mediante la creación de un script de cambio de base de datos.
- Use Migraciones de Code First para actualizar el esquema de la base de datos.
Para este tutorial se usa Migraciones de Code First.
Actualice el método Seed para que proporcione un valor para la nueva columna. Abra el archivo Migrations\Configuration.cs y agregue un 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 la solución, abra la ventana Consola del Administrador de paquetes y escriba el siguiente comando:
add-migration AddRatingMig
El comando add-migration
indica al marco de migración que examine el modelo de película actual con el esquema de base de datos de película actual y cree el código necesario para migrar la base de datos al nuevo modelo. AddRatingMig es arbitrario y se usa para asignar un nombre al archivo de migración. Resulta útil usar un nombre descriptivo para el paso de migración.
Cuando este comando finaliza, Visual Studio abre el archivo de clase que define la nueva clase derivada DbMigration
y, en el método Up
, puede ver el código que crea la nueva columna.
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 la solución y escriba el comando "update-database" en la ventana Consola del administrador de paquetes.
En la imagen siguiente se muestra la salida en la ventana Consola del administrador de paquetes (la marca de fecha pendiente AddRatingMig será diferente).
Vuelva a ejecutar la aplicación y vaya a la dirección URL de /Movies. Puede ver el nuevo campo Clasificación.
Haga clic en el vínculo Crear nueva para agregar una nueva película. Tenga en cuenta que puede agregar una clasificación.
Haga clic en Crear. La nueva película, incluida la clasificación, ahora aparece en la lista de películas:
También debe agregar el campo Rating
a las plantillas de vista Editar, Detalles y SearchIndex.
Puede volver a escribir el comando "update-database" en la ventana Consola del administrador de paquetes y no se realizarían cambios, ya que el esquema coincide con el modelo.
En esta sección ha visto cómo puede modificar objetos de modelo y mantener la base de datos sincronizada con los cambios. También ha aprendido a rellenar una base de datos recién creada con datos de ejemplo para probar escenarios. A continuación, verá cómo puede agregar lógica de validación más completa a las clases de modelo y permitir que se apliquen algunas reglas de negocios.