Comparteix a través de


Parte 8. Adición de un nuevo campo a una aplicación de ASP.NET Core MVC

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulte la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

Por Rick Anderson

En esta sección, Migraciones de Entity Framework se usa para:

  • Agregar un campo nuevo al modelo.
  • Migrar el nuevo campo a la base de datos.

Cuando Entity Framework (EF) se usa para crear automáticamente una base de datos a partir de clases de modelo:

  • Se agrega una tabla a la base de datos para realizar un seguimiento del esquema de la base de datos.
  • La base de datos se comprueba para sincronizarse con las clases del modelo desde las que se generó. Si no está sincronizado, EF produce una excepción. Esto facilita la detección de problemas de código o base de datos incoherentes.

Adición de una propiedad de clasificación al modelo Movie

Agregue una propiedad Rating a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
    public string? Rating {  get; set; }
}

Compilar la aplicación

Presione Ctrl+Mayús+B

Dado que ha agregado un campo nuevo a la clase Movie, debe actualizar la lista de enlaces de propiedades para que se incluya esta propiedad nueva. En MoviesController.cs, actualice el atributo [Bind] de los métodos de acción Create y Edit para incluir la propiedad Rating:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Actualice las plantillas de vista para mostrar, crear y editar la nueva propiedad Rating en la vista del explorador.

Edite el archivo /Views/Movies/Index.cshtml y agregue un campo Rating:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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>
                    <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>

Actualice /Views/Movies/Create.cshtml con un campo Rating.

Puede copiar o pegar el elemento "form group" anterior y permitir que IntelliSense le ayude a actualizar los campos. IntelliSense funciona con asistentes de etiquetas.

El desarrollador ha escrito la letra R para el valor del atributo de asp-for en el segundo elemento de etiqueta de la vista. Ha aparecido un menú contextual de IntelliSense que muestra los campos disponibles, incluido Rating, que se resalta en la lista automáticamente. Cuando el desarrollador hace clic en el campo o presiona Entrar en el teclado, el valor se establece en Rating.

Agregue la propiedad Rating al resto de plantillas de vista Create.cshtml, Delete.cshtml, Details.cshtml y Edit.cshtml.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, aunque es conveniente realizarlo con cada new Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

La aplicación no funciona hasta que la base de datos se actualiza para incluir el nuevo campo. Si se ejecuta ahora, se produce la siguiente SqlException:

SqlException: Invalid column name 'Rating'.

Este error se produce porque la clase del modelo Movie actualizada es diferente a la 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:

  1. 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 al principio del ciclo de desarrollo 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 juntos. 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. Se trata de un buen enfoque para el desarrollo inicial y cuando se usa SQLite.

  2. 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.

  3. Use Migraciones de Entity Framework para actualizar el esquema de la base de datos.

En este tutorial, se usa Migraciones de Entity Framework.

En el menú Herramientas, seleccione Administrador de paquetes NuGet >Consola del Administrador de paquetes.

Menú de PMC

En la Consola del Administrador de paquetes, escriba el siguiente comando:

Add-Migration Rating

El comando Add-Migration indica el marco de trabajo de migración para examinar el modelo Movie actual con el esquema de base de datos Movie actual y para crear el código con el que se migrará la base de datos al nuevo modelo.

El nombre "Rating" es arbitrario y se usa para asignar nombre al archivo de migración. Resulta útil emplear un nombre descriptivo para el archivo de migración.

Si se eliminan todos los registros de la base de datos, el método de inicialización inicializa la base de datos e incluye el campo Rating.

En la Consola del Administrador de paquetes, escriba el siguiente comando:

Update-Database

El comando Update-Database ejecuta el método Up en las migraciones que no se aplicaron.

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating.

En esta sección, Migraciones de Entity Framework Code First se utiliza para:

  • Agregar un campo nuevo al modelo.
  • Migrar el nuevo campo a la base de datos.

Al usar Code First de EF para crear una base de datos automáticamente, Code First hace lo siguiente:

  • Agrega una tabla a la base de datos para realizar un seguimiento del esquema de la base de datos.
  • Comprueba que la base de datos está sincronizada con las clases del modelo desde las que se ha generado. Si no está sincronizado, EF produce una excepción. Esto facilita la detección de problemas de código o base de datos incoherentes.

Adición de una propiedad de clasificación al modelo Movie

Agregue una propiedad Rating a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
    public string? Rating {  get; set; }
}

Compilar la aplicación

Presione Ctrl+Mayús+B

Dado que ha agregado un campo nuevo a la clase Movie, debe actualizar la lista de enlaces de propiedades para que se incluya esta propiedad nueva. En MoviesController.cs, actualice el atributo [Bind] de los métodos de acción Create y Edit para incluir la propiedad Rating:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Actualice las plantillas de vista para mostrar, crear y editar la nueva propiedad Rating en la vista del explorador.

Edite el archivo /Views/Movies/Index.cshtml y agregue un campo Rating:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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>
                    <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>

Actualice /Views/Movies/Create.cshtml con un campo Rating.

Puede copiar o pegar el elemento "form group" anterior y permitir que IntelliSense le ayude a actualizar los campos. IntelliSense funciona con asistentes de etiquetas.

El desarrollador ha escrito la letra R para el valor del atributo de asp-for en el segundo elemento de etiqueta de la vista. Ha aparecido un menú contextual de IntelliSense que muestra los campos disponibles, incluido Rating, que se resalta en la lista automáticamente. Cuando el desarrollador hace clic en el campo o presiona Entrar en el teclado, el valor se establece en Rating.

Actualice el resto de las plantillas.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, aunque es conveniente realizarlo con cada new Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

La aplicación no funciona hasta que la base de datos se actualiza para incluir el nuevo campo. Si se ejecuta ahora, se produce la siguiente SqlException:

SqlException: Invalid column name 'Rating'.

Este error se produce porque la clase del modelo Movie actualizada es diferente a la 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:

  1. 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 al principio del ciclo de desarrollo 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 juntos. 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. Se trata de un buen enfoque para el desarrollo inicial y cuando se usa SQLite.

  2. 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.

  3. Use Migraciones de Code First para actualizar el esquema de la base de datos.

En este tutorial se usa Migraciones de Code First.

En el menú Herramientas, seleccione Administrador de paquetes NuGet >Consola del Administrador de paquetes.

Menú de PMC

En PCM, escriba los siguientes comandos:

Add-Migration Rating
Update-Database

El comando Add-Migration indica el marco de trabajo de migración para examinar el modelo Movie actual con el esquema de base de datos Movie actual y para crear el código con el que se migrará la base de datos al nuevo modelo.

El nombre "Rating" es arbitrario y se usa para asignar nombre al archivo de migración. Resulta útil emplear un nombre descriptivo para el archivo de migración.

Si se eliminan todos los registros de la base de datos, el método de inicialización inicializa la base de datos e incluye el campo Rating.

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating.

En esta sección, Migraciones de Entity Framework Code First se utiliza para:

  • Agregar un campo nuevo al modelo.
  • Migrar el nuevo campo a la base de datos.

Al usar Code First de EF para crear una base de datos automáticamente, Code First hace lo siguiente:

  • Agrega una tabla a la base de datos para realizar un seguimiento del esquema de la base de datos.
  • Comprueba que la base de datos está sincronizada con las clases del modelo desde las que se ha generado. Si no está sincronizado, EF produce una excepción. Esto facilita la detección de problemas de código o base de datos incoherentes.

Adición de una propiedad de clasificación al modelo Movie

Agregue una propiedad Rating a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

public class Movie
{
    public int Id { get; set; }
    public string? Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string? Genre { get; set; }
    
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }
    public string? Rating {  get; set; }
}

Compilar la aplicación

Presione Ctrl+Mayús+B

Dado que ha agregado un campo nuevo a la clase Movie, debe actualizar la lista de enlaces de propiedades para que se incluya esta propiedad nueva. En MoviesController.cs, actualice el atributo [Bind] de los métodos de acción Create y Edit para incluir la propiedad Rating:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Actualice las plantillas de vista para mostrar, crear y editar la nueva propiedad Rating en la vista del explorador.

Edite el archivo /Views/Movies/Index.cshtml y agregue un campo Rating:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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>
                    <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>

Actualice /Views/Movies/Create.cshtml con un campo Rating.

Puede copiar o pegar el elemento "form group" anterior y permitir que IntelliSense le ayude a actualizar los campos. IntelliSense funciona con asistentes de etiquetas.

El desarrollador ha escrito la letra R para el valor del atributo de asp-for en el segundo elemento de etiqueta de la vista. Ha aparecido un menú contextual de IntelliSense que muestra los campos disponibles, incluido Rating, que se resalta en la lista automáticamente. Cuando el desarrollador hace clic en el campo o presiona Entrar en el teclado, el valor se establece en Rating.

Actualice el resto de las plantillas.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, aunque es conveniente realizarlo con cada new Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

La aplicación no funciona hasta que la base de datos se actualiza para incluir el nuevo campo. Si se ejecuta ahora, se produce la siguiente SqlException:

SqlException: Invalid column name 'Rating'.

Este error se produce porque la clase del modelo Movie actualizada es diferente a la 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:

  1. 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 al principio del ciclo de desarrollo 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 juntos. 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. Se trata de un buen enfoque para el desarrollo inicial y cuando se usa SQLite.

  2. 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.

  3. Use Migraciones de Code First para actualizar el esquema de la base de datos.

En este tutorial se usa Migraciones de Code First.

En el menú Herramientas, seleccione Administrador de paquetes NuGet >Consola del Administrador de paquetes.

Menú de PMC

En PCM, escriba los siguientes comandos:

Add-Migration Rating
Update-Database

El comando Add-Migration indica el marco de trabajo de migración para examinar el modelo Movie actual con el esquema de base de datos Movie actual y para crear el código con el que se migrará la base de datos al nuevo modelo.

El nombre "Rating" es arbitrario y se usa para asignar nombre al archivo de migración. Resulta útil emplear un nombre descriptivo para el archivo de migración.

Si se eliminan todos los registros de la base de datos, el método de inicialización inicializa la base de datos e incluye el campo Rating.

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating.

En esta sección, Migraciones de Entity Framework Code First se utiliza para:

  • Agregar un campo nuevo al modelo.
  • Migrar el nuevo campo a la base de datos.

Al usar Code First de EF para crear una base de datos automáticamente, Code First hace lo siguiente:

  • Agrega una tabla a la base de datos para realizar un seguimiento del esquema de la base de datos.
  • Comprueba que la base de datos está sincronizada con las clases del modelo desde las que se ha generado. Si no está sincronizado, EF produce una excepción. Esto facilita la detección de problemas de código o base de datos incoherentes.

Adición de una propiedad de clasificación al modelo Movie

Agregue una propiedad Rating a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string? Rating {  get; set; }
    }
}

Compilar la aplicación

Ctrl+Mayús+B

Dado que ha agregado un campo nuevo a la clase Movie, debe actualizar la lista de enlaces de propiedades para que se incluya esta propiedad nueva. En MoviesController.cs, actualice el atributo [Bind] de los métodos de acción Create y Edit para incluir la propiedad Rating:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Actualice las plantillas de vista para mostrar, crear y editar la nueva propiedad Rating en la vista del explorador.

Edite el archivo /Views/Movies/Index.cshtml y agregue un campo Rating:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies)
        {
            <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>
                    <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>

Actualice /Views/Movies/Create.cshtml con un campo Rating.

Puede copiar o pegar el elemento "form group" anterior y permitir que IntelliSense le ayude a actualizar los campos. IntelliSense funciona con asistentes de etiquetas.

El desarrollador ha escrito la letra R para el valor del atributo de asp-for en el segundo elemento de etiqueta de la vista. Ha aparecido un menú contextual de IntelliSense que muestra los campos disponibles, incluido Rating, que se resalta en la lista automáticamente. Cuando el desarrollador hace clic en el campo o presiona Entrar en el teclado, el valor se establece en Rating.

Actualice el resto de las plantillas.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, aunque es conveniente realizarlo con cada new Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

La aplicación no funciona hasta que la base de datos se actualiza para incluir el nuevo campo. Si se ejecuta ahora, se produce la siguiente SqlException:

SqlException: Invalid column name 'Rating'.

Este error se produce porque la clase del modelo Movie actualizada es diferente a la 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:

  1. 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 al principio del ciclo de desarrollo 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 juntos. 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. Se trata de un buen enfoque para el desarrollo inicial y cuando se usa SQLite.

  2. 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.

  3. Use Migraciones de Code First para actualizar el esquema de la base de datos.

En este tutorial se usa Migraciones de Code First.

En el menú Herramientas, seleccione Administrador de paquetes NuGet >Consola del Administrador de paquetes.

Menú de PMC

En PCM, escriba los siguientes comandos:

Add-Migration Rating
Update-Database

El comando Add-Migration indica el marco de trabajo de migración para examinar el modelo Movie actual con el esquema de base de datos Movie actual y para crear el código con el que se migrará la base de datos al nuevo modelo.

El nombre "Rating" es arbitrario y se usa para asignar nombre al archivo de migración. Resulta útil emplear un nombre descriptivo para el archivo de migración.

Si se eliminan todos los registros de la base de datos, el método de inicialización inicializa la base de datos e incluye el campo Rating.

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating.

En esta sección, Migraciones de Entity Framework Code First se utiliza para:

  • Agregar un campo nuevo al modelo.
  • Migrar el nuevo campo a la base de datos.

Al usar Code First de EF para crear una base de datos automáticamente, Code First hace lo siguiente:

  • Agrega una tabla a la base de datos para realizar un seguimiento del esquema de la base de datos.
  • Comprueba que la base de datos está sincronizada con las clases del modelo desde las que se ha generado. Si no está sincronizado, EF produce una excepción. Esto facilita la detección de problemas de código o base de datos incoherentes.

Adición de una propiedad de clasificación al modelo Movie

Agregue una propiedad Rating a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; }
    }
}

Compilar la aplicación

Ctrl+Mayús+B

Dado que ha agregado un campo nuevo a la clase Movie, debe actualizar la lista de enlaces de propiedades para que se incluya esta propiedad nueva. En MoviesController.cs, actualice el atributo [Bind] de los métodos de acción Create y Edit para incluir la propiedad Rating:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Actualice las plantillas de vista para mostrar, crear y editar la nueva propiedad Rating en la vista del explorador.

Edite el archivo /Views/Movies/Index.cshtml y agregue un campo Rating:

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Rating)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model.Movies)
    {
        <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>

Actualice /Views/Movies/Create.cshtml con un campo Rating.

Puede copiar o pegar el elemento "form group" anterior y permitir que IntelliSense le ayude a actualizar los campos. IntelliSense funciona con asistentes de etiquetas.

El desarrollador ha escrito la letra R para el valor del atributo de asp-for en el segundo elemento de etiqueta de la vista. Ha aparecido un menú contextual de IntelliSense que muestra los campos disponibles, incluido Rating, que se resalta en la lista automáticamente. Cuando el desarrollador hace clic en el campo o presiona Entrar en el teclado, el valor se establece en Rating.

Actualice el resto de las plantillas.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, aunque es conveniente realizarlo con cada new Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

La aplicación no funciona hasta que la base de datos se actualiza para incluir el nuevo campo. Si se ejecuta ahora, se produce la siguiente SqlException:

SqlException: Invalid column name 'Rating'.

Este error se produce porque la clase del modelo Movie actualizada es diferente a la 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:

  1. 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 al principio del ciclo de desarrollo 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 juntos. 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. Se trata de un buen enfoque para el desarrollo inicial y cuando se usa SQLite.

  2. 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.

  3. Use Migraciones de Code First para actualizar el esquema de la base de datos.

En este tutorial se usa Migraciones de Code First.

En el menú Herramientas, seleccione Administrador de paquetes NuGet >Consola del Administrador de paquetes.

Menú de PMC

En PCM, escriba los siguientes comandos:

Add-Migration Rating
Update-Database

El comando Add-Migration indica el marco de trabajo de migración para examinar el modelo Movie actual con el esquema de base de datos Movie actual y para crear el código con el que se migrará la base de datos al nuevo modelo.

El nombre "Rating" es arbitrario y se usa para asignar nombre al archivo de migración. Resulta útil emplear un nombre descriptivo para el archivo de migración.

Si se eliminan todos los registros de la base de datos, el método de inicialización inicializa la base de datos e incluye el campo Rating.

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating.

En esta sección, Migraciones de Entity Framework Code First se utiliza para:

  • Agregar un campo nuevo al modelo.
  • Migrar el nuevo campo a la base de datos.

Al usar Code First de EF para crear una base de datos automáticamente, Code First hace lo siguiente:

  • Agrega una tabla a la base de datos para realizar un seguimiento del esquema de la base de datos.
  • Comprueba que la base de datos está sincronizada con las clases del modelo desde las que se ha generado. Si no está sincronizado, EF produce una excepción. Esto facilita la detección de problemas de código o base de datos incoherentes.

Adición de una propiedad de clasificación al modelo Movie

Agregue una propiedad Rating a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }

        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; }
    }
}

Compilar la aplicación

Ctrl+Mayús+B

Dado que ha agregado un campo nuevo a la clase Movie, debe actualizar la lista de enlaces de propiedades para que se incluya esta propiedad nueva. En MoviesController.cs, actualice el atributo [Bind] de los métodos de acción Create y Edit para incluir la propiedad Rating:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Actualice las plantillas de vista para mostrar, crear y editar la nueva propiedad Rating en la vista del explorador.

Edite el archivo /Views/Movies/Index.cshtml y agregue un campo Rating:

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Rating)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model.Movies)
    {
        <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>

Actualice /Views/Movies/Create.cshtml con un campo Rating.

Puede copiar o pegar el elemento "form group" anterior y permitir que IntelliSense le ayude a actualizar los campos. IntelliSense funciona con asistentes de etiquetas.

El desarrollador ha escrito la letra R para el valor del atributo de asp-for en el segundo elemento de etiqueta de la vista. Ha aparecido un menú contextual de IntelliSense que muestra los campos disponibles, incluido Rating, que se resalta en la lista automáticamente. Cuando el desarrollador hace clic en el campo o presiona Entrar en el teclado, el valor se establece en Rating.

Actualice el resto de las plantillas.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, aunque es conveniente realizarlo con cada new Movie.

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "R",
    Price = 7.99M
},

La aplicación no funciona hasta que la base de datos se actualiza para incluir el nuevo campo. Si se ejecuta ahora, se produce la siguiente SqlException:

SqlException: Invalid column name 'Rating'.

Este error se produce porque la clase del modelo Movie actualizada es diferente a la 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:

  1. 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 al principio del ciclo de desarrollo 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 juntos. 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. Se trata de un buen enfoque para el desarrollo inicial y cuando se usa SQLite.

  2. 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.

  3. Use Migraciones de Code First para actualizar el esquema de la base de datos.

En este tutorial se usa Migraciones de Code First.

En el menú Herramientas, seleccione Administrador de paquetes NuGet >Consola del Administrador de paquetes.

Menú de PMC

En PCM, escriba los siguientes comandos:

Add-Migration Rating
Update-Database

El comando Add-Migration indica el marco de trabajo de migración para examinar el modelo Movie actual con el esquema de base de datos Movie actual y para crear el código con el que se migrará la base de datos al nuevo modelo.

El nombre "Rating" es arbitrario y se usa para asignar nombre al archivo de migración. Resulta útil emplear un nombre descriptivo para el archivo de migración.

Si se eliminan todos los registros de la base de datos, el método de inicialización inicializa la base de datos e incluye el campo Rating.

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating.