Parte 7. Adición de un campo nuevo a una instancia de Razor Pages en ASP.NET Core

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.

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 Code First se utiliza para:

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

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

  • Agrega una tabla __EFMigrationsHistory a la base de datos para ayudar a saber si el esquema de la base de datos está sincronizado con las clases del modelo a partir del que se ha generado.
  • Si las clases del modelo no están sincronizadas con la base de datos, produce una excepción.

La comprobación automática de la sincronización del esquema y el modelo facilita la detección de problemas de código de base de datos incoherente.

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

  1. Abra el archivo Models/Movie.cs y agregue una propiedad Rating:

    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Edite Pages/Movies/Index.cshtml y agregue un campo Rating: .

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <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-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  3. Actualice las páginas siguientes con un campo Rating:

La aplicación no funcionará hasta que la base de datos se actualiza para incluir el nuevo campo. Al ejecutar la aplicación sin actualizar la base de datos, se produce una excepción SqlException:

SqlException: Invalid column name 'Rating'.

La excepción SqlException se debe a que la clase del modelo Movie actualizado es diferente del esquema de la tabla Movie de la base de datos. 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 con el nuevo esquema de la clase del modelo. Este enfoque resulta conveniente al principio del ciclo de desarrollo, permite a los desarrolladores hacer evolucionar a la vez y de manera rápida el esquema del modelo y la base de datos. El inconveniente es que se pierden los datos existentes en la base de datos. No use este enfoque en una base de datos de producción. El hecho de quitar la base de datos en los cambios de esquema y el usar un inicializador para inicializar automáticamente la base de datos con datos de prueba suele ser una forma productiva de desarrollar una aplicación.
  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. Haga 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.

Para este tutorial, use Migraciones de Code First.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, pero realice este cambio para cada bloque new Movie.

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

Vea el archivo completado SeedData.cs.

Compilar la aplicación

Presione Ctrl+Mayús+B

Agregar una migración para el campo de clasificación

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

  2. En PCM, escriba los siguientes comandos:

    Add-Migration Rating
    Update-Database
    

El comando Add-Migration indica al marco de trabajo que:

  • Compare el modelo Movie con el esquema de base de datos Movie.
  • Cree el código pertinente para migrar el esquema de 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.

El comando Update-Database le indica al marco que aplique los cambios de esquema a la base de datos y que conserve los datos existentes.

Si elimina todos los registros de la base de datos, el inicializador inicializará la base de datos e incluirá el campo Rating. Puede hacerlo con los vínculos de eliminación en el explorador o desde el Explorador de objetos de SQL Server (SSOX).

Otra opción es eliminar la base de datos y usar las migraciones para volver a crear la base de datos. Para eliminar la base de datos de SSOX:

  1. Seleccione la base de datos en SSOX.

  2. Haga clic con el botón derecho en la base de datos y seleccione Eliminar.

  3. Active Cerrar las conexiones existentes.

  4. Seleccione Aceptar.

  5. En la PMC, actualice la base de datos:

    Update-Database
    

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating. Si la base de datos no se ha propagado, establezca un punto de interrupción en el método SeedData.Initialize.

Pasos siguientes

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

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

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

  • Agrega una tabla __EFMigrationsHistory a la base de datos para ayudar a saber si el esquema de la base de datos está sincronizado con las clases del modelo a partir del que se ha generado.
  • Si las clases del modelo no están sincronizadas con la base de datos, produce una excepción.

La comprobación automática de la sincronización del esquema y el modelo facilita la detección de problemas de código de base de datos incoherente.

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

  1. Abra el archivo Models/Movie.cs y agregue una propiedad Rating:

    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Edite Pages/Movies/Index.cshtml y agregue un campo Rating: .

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <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-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  3. Actualice las páginas siguientes con un campo Rating:

La aplicación no funcionará hasta que la base de datos se actualiza para incluir el nuevo campo. Al ejecutar la aplicación sin actualizar la base de datos, se produce una excepción SqlException:

SqlException: Invalid column name 'Rating'.

La excepción SqlException se debe a que la clase del modelo Movie actualizado es diferente del esquema de la tabla Movie de la base de datos. 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 con el nuevo esquema de la clase del modelo. Este enfoque resulta conveniente al principio del ciclo de desarrollo, permite a los desarrolladores hacer evolucionar a la vez y de manera rápida el esquema del modelo y la base de datos. El inconveniente es que se pierden los datos existentes en la base de datos. No use este enfoque en una base de datos de producción. El hecho de quitar la base de datos en los cambios de esquema y el usar un inicializador para inicializar automáticamente la base de datos con datos de prueba suele ser una forma productiva de desarrollar una aplicación.
  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. Haga 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.

Para este tutorial, use Migraciones de Code First.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, pero realice este cambio para cada bloque new Movie.

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

Vea el archivo completado SeedData.cs.

Compilar la aplicación

Presione Ctrl+Mayús+B

Agregar una migración para el campo de clasificación

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

  2. En PCM, escriba los siguientes comandos:

    Add-Migration Rating
    Update-Database
    

El comando Add-Migration indica al marco de trabajo que:

  • Compare el modelo Movie con el esquema de base de datos Movie.
  • Cree el código pertinente para migrar el esquema de 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.

El comando Update-Database le indica al marco que aplique los cambios de esquema a la base de datos y que conserve los datos existentes.

Si elimina todos los registros de la base de datos, el inicializador inicializará la base de datos e incluirá el campo Rating. Puede hacerlo con los vínculos de eliminación en el explorador o desde el Explorador de objetos de SQL Server (SSOX).

Otra opción es eliminar la base de datos y usar las migraciones para volver a crear la base de datos. Para eliminar la base de datos de SSOX:

  1. Seleccione la base de datos en SSOX.

  2. Haga clic con el botón derecho en la base de datos y seleccione Eliminar.

  3. Active Cerrar las conexiones existentes.

  4. Seleccione Aceptar.

  5. En la PMC, actualice la base de datos:

    Update-Database
    

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating. Si la base de datos no se ha propagado, establezca un punto de interrupción en el método SeedData.Initialize.

Pasos siguientes

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

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

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

  • Agrega una tabla __EFMigrationsHistory a la base de datos para ayudar a saber si el esquema de la base de datos está sincronizado con las clases del modelo a partir del que se ha generado.
  • Si las clases del modelo no están sincronizadas con la base de datos, produce una excepción.

La comprobación automática de la sincronización del esquema y el modelo facilita la detección de problemas de código de base de datos incoherente.

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

  1. Abra el archivo Models/Movie.cs y agregue una propiedad Rating:

    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Edite Pages/Movies/Index.cshtml y agregue un campo Rating: .

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <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-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  3. Actualice las páginas siguientes con un campo Rating:

La aplicación no funcionará hasta que la base de datos se actualiza para incluir el nuevo campo. Al ejecutar la aplicación sin actualizar la base de datos, se produce una excepción SqlException:

SqlException: Invalid column name 'Rating'.

La excepción SqlException se debe a que la clase del modelo Movie actualizado es diferente del esquema de la tabla Movie de la base de datos. 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 con el nuevo esquema de la clase del modelo. Este enfoque resulta conveniente al principio del ciclo de desarrollo, permite a los desarrolladores hacer evolucionar a la vez y de manera rápida el esquema del modelo y la base de datos. El inconveniente es que se pierden los datos existentes en la base de datos. No use este enfoque en una base de datos de producción. El hecho de quitar la base de datos en los cambios de esquema y el usar un inicializador para inicializar automáticamente la base de datos con datos de prueba suele ser una forma productiva de desarrollar una aplicación.
  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. Haga 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.

Para este tutorial, use Migraciones de Code First.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, pero realice este cambio para cada bloque new Movie.

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

Vea el archivo completado SeedData.cs.

Compile la solución.

Agregar una migración para el campo de clasificación

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

  2. En PCM, escriba los siguientes comandos:

    Add-Migration Rating
    Update-Database
    

El comando Add-Migration indica al marco de trabajo que:

  • Compare el modelo Movie con el esquema de base de datos Movie.
  • Cree el código pertinente para migrar el esquema de 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.

El comando Update-Database le indica al marco que aplique los cambios de esquema a la base de datos y que conserve los datos existentes.

Si elimina todos los registros de la base de datos, el inicializador inicializará la base de datos e incluirá el campo Rating. Puede hacerlo con los vínculos de eliminación en el explorador o desde el Explorador de objetos de SQL Server (SSOX).

Otra opción es eliminar la base de datos y usar las migraciones para volver a crear la base de datos. Para eliminar la base de datos de SSOX:

  1. Seleccione la base de datos en SSOX.

  2. Haga clic con el botón derecho en la base de datos y seleccione Eliminar.

  3. Active Cerrar las conexiones existentes.

  4. Seleccione Aceptar.

  5. En la PMC, actualice la base de datos:

    Update-Database
    

Ejecute la aplicación y compruebe que puede crear, editar o mostrar vídeos con un campo Rating. Si la base de datos no se ha propagado, establezca un punto de interrupción en el método SeedData.Initialize.

Pasos siguientes

Vea o descargue el código de ejemplo (cómo descargarlo).

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

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

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

  • Agrega una tabla __EFMigrationsHistory a la base de datos para ayudar a saber si el esquema de la base de datos está sincronizado con las clases del modelo a partir del que se ha generado.
  • Si las clases del modelo no están sincronizadas con la base de datos, EF produce una excepción.

La comprobación automática de la sincronización del esquema y el modelo facilita la detección de problemas de código de base de datos incoherente.

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

  1. Abra el archivo Models/Movie.cs y agregue una propiedad Rating:

    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; }
    }
    
  2. Compile la aplicación.

  3. Edite Pages/Movies/Index.cshtml y agregue un campo Rating:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <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-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  4. Actualice las páginas siguientes con un campo Rating:

La aplicación no funcionará hasta que la base de datos se actualiza para incluir el nuevo campo. Al ejecutar la aplicación sin actualizar la base de datos, se produce una excepción SqlException:

SqlException: Invalid column name 'Rating'.

La excepción SqlException se debe a que la clase del modelo Movie actualizado es diferente del esquema de la tabla Movie de la base de datos. 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 con el nuevo esquema de la clase del modelo. Este enfoque resulta conveniente al principio del ciclo de desarrollo, permite desarrollar a la vez y de manera rápida el esquema del modelo y la base de datos. El inconveniente es que se pierden los datos existentes en la base de datos. No use este enfoque en una base de datos de producción. El hecho de quitar la base de datos en los cambios de esquema y el usar un inicializador para inicializar automáticamente la base de datos con datos de prueba suele ser una forma productiva de desarrollar una aplicación.

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

Para este tutorial, use Migraciones de Code First.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, pero realice este cambio para cada bloque new Movie.

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

Vea el archivo completado SeedData.cs.

Compile la solución.

Agregar una migración para el campo de clasificación

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

  2. En PCM, escriba los siguientes comandos:

    Add-Migration Rating
    Update-Database
    

El comando Add-Migration indica al marco de trabajo que:

  • Compare el modelo Movie con el esquema de base de datos Movie.
  • Cree el código pertinente para migrar el esquema de 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.

El comando Update-Database le indica al marco que aplique los cambios de esquema a la base de datos y que conserve los datos existentes.

Si elimina todos los registros de la base de datos, el inicializador inicializará la base de datos e incluirá el campo Rating. Puede hacerlo con los vínculos de eliminación en el explorador o desde el Explorador de objetos de SQL Server (SSOX).

Otra opción es eliminar la base de datos y usar las migraciones para volver a crear la base de datos. Para eliminar la base de datos de SSOX:

  1. Seleccione la base de datos en SSOX.

  2. Haga clic con el botón derecho en la base de datos y seleccione Eliminar.

  3. Active Cerrar las conexiones existentes.

  4. Seleccione Aceptar.

  5. En la PMC, actualice la base de datos:

    Update-Database
    

Ejecute la aplicación y compruebe que puede crear, editar o mostrar películas con un campo Rating. Si la base de datos no se ha propagado, establezca un punto de interrupción en el método SeedData.Initialize.

Pasos siguientes

Vea o descargue el código de ejemplo (cómo descargarlo).

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

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

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

  • Agrega una tabla __EFMigrationsHistory a la base de datos para ayudar a saber si el esquema de la base de datos está sincronizado con las clases del modelo a partir del que se ha generado.
  • Si las clases del modelo no están sincronizadas con la base de datos, EF produce una excepción.

La comprobación automática de la sincronización del esquema y el modelo facilita la detección de problemas de código de base de datos incoherente.

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

  1. Abra el archivo Models/Movie.cs y agregue una propiedad Rating:

    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; }
    }
    
  2. Compile la aplicación.

  3. Edite Pages/Movies/Index.cshtml y agregue un campo Rating:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <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-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  4. Actualice las páginas siguientes con un campo Rating:

La aplicación no funcionará hasta que la base de datos se actualiza para incluir el nuevo campo. Al ejecutar la aplicación sin actualizar la base de datos, se produce una excepción SqlException:

SqlException: Invalid column name 'Rating'.

La excepción SqlException se debe a que la clase del modelo Movie actualizado es diferente del esquema de la tabla Movie de la base de datos. 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 con el nuevo esquema de la clase del modelo. Este enfoque resulta conveniente al principio del ciclo de desarrollo, permite desarrollar a la vez y de manera rápida el esquema del modelo y la base de datos. El inconveniente es que se pierden los datos existentes en la base de datos. No use este enfoque en una base de datos de producción. El hecho de quitar la base de datos en los cambios de esquema y el usar un inicializador para inicializar automáticamente la base de datos con datos de prueba suele ser una forma productiva de desarrollar una aplicación.

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

Para este tutorial, use Migraciones de Code First.

Actualice la clase SeedData para que proporcione un valor para la nueva columna. A continuación se muestra un cambio de ejemplo, pero realice este cambio para cada bloque new Movie.

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

Vea el archivo completado SeedData.cs.

Compile la solución.

Agregar una migración para el campo de clasificación

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

  2. En PCM, escriba los siguientes comandos:

    Add-Migration Rating
    Update-Database
    

El comando Add-Migration indica al marco de trabajo que:

  • Compare el modelo Movie con el esquema de base de datos Movie.
  • Cree el código pertinente para migrar el esquema de 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.

El comando Update-Database le indica al marco que aplique los cambios de esquema a la base de datos y que conserve los datos existentes.

Si elimina todos los registros de la base de datos, el inicializador inicializará la base de datos e incluirá el campo Rating. Puede hacerlo con los vínculos de eliminación en el explorador o desde el Explorador de objetos de SQL Server (SSOX).

Otra opción es eliminar la base de datos y usar las migraciones para volver a crear la base de datos. Para eliminar la base de datos de SSOX:

  • Seleccione la base de datos en SSOX.

  • Haga clic con el botón derecho en la base de datos y seleccione Eliminar.

  • Active Cerrar las conexiones existentes.

  • Seleccione Aceptar.

  • En la PMC, actualice la base de datos:

    Update-Database
    

Ejecute la aplicación y compruebe que puede crear, editar o mostrar películas con un campo Rating. Si la base de datos no se ha propagado, establezca un punto de interrupción en el método SeedData.Initialize.

Pasos siguientes