Dela via


Del 7, lägg till ett nytt fält på en Razor-sida i ASP.NET Core

Notera

Det här är inte den senaste versionen av den här artikeln. För den aktuella versionen, se version av .NET 9 av den här artikeln.

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. För den aktuella versionen, se .NET 9-versionen av den här artikeln.

Viktig

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.

Av Rick Anderson

I det här avsnittet Entity Framework Core (EF Core) används för att definiera databasschemat baserat på appens modellklass:

  • Lägg till ett nytt fält i modellen.
  • Migrera den nya fältschemaändringen till databasen.

Den EF Core metoden möjliggör en mer flexibel utvecklingsprocess. Utvecklaren arbetar direkt med appens datamodell medan databasschemat skapas och sedan synkroniseras, allt utan att utvecklaren behöver växla kontexter till och från ett databashanteringsverktyg. En översikt över Entity Framework Core och dess fördelar finns i Entity Framework Core.

Använda EF Code för att automatiskt skapa och spåra en databas:

  • Lägger till en __EFMigrationsHistory tabell i databasen för att spåra om schemat för databasen är synkroniserat med de modellklasser som den genererades från.
  • Utlöser ett undantag om modellklasserna inte är synkroniserade med databasen.

Automatisk verifiering av att schemat och modellen är synkroniserade gör det enklare att hitta inkonsekventa problem med databaskod.

Lägga till en klassificeringsegenskap i filmmodellen

  1. Öppna filen Models/Movie.cs och lägg till en egenskap för 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. Redigera Pages/Movies/Index.cshtmloch lägg till ett Rating fält:

    @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>
            <label>Title: <input type="text" asp-for="SearchString" /></label>
            <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. Uppdatera följande sidor med ett Rating fält:

Appen fungerar inte förrän databasen har uppdaterats för att inkludera det nya fältet. När du kör appen utan en uppdatering av databasen utlöss en SqlException:

SqlException: Invalid column name 'Rating'.

Undantaget SqlException orsakas av att den uppdaterade filmmodellklassen skiljer sig från schemat för tabellen Film i databasen. Det finns ingen Rating kolumn i databastabellen.

Det finns några metoder för att lösa felet:

  1. Låt Entity Framework automatiskt släppa och återskapa databasen med hjälp av det nya modellklassschemat. Den här metoden är praktisk tidigt i utvecklingscykeln, vilket gör att utvecklare snabbt kan utveckla modellen och databasschemat tillsammans. Nackdelen är att befintliga data i databasen går förlorade. Använd inte den här metoden i en produktionsdatabas! Att ta bort databasen vid schemaändringar och använda en initierare för att automatiskt seeda databasen med testdata är ofta ett produktivt sätt att utveckla en app.
  2. Ändra uttryckligen schemat för den befintliga databasen så att den matchar modellklasserna. Fördelen med den här metoden är att behålla data. Gör den här ändringen antingen manuellt eller genom att skapa ett databasändringsskript.
  3. Använd EF Core Migreringar för att uppdatera databasschemat.

I den här handledningen använder du EF Core Migreringar.

Uppdatera klassen SeedData så att den ger ett värde för den nya kolumnen. En exempeländring visas nedan, men gör den här ändringen för varje new Movie block.

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

Se den slutförda filen SeedData.cs .

Skapa appen

Tryck på Ctrl+Skift+B

Lägga till en migrering för klassificeringsfältet

  1. På menyn Verktyg väljer du NuGet Package Manager > Package Manager Console.

  2. I Package Manager Console (PMC) anger du följande kommando:

    Add-Migration Rating
    

Kommandot Add-Migration instruerar ramverket att:

  • Jämför Movie-modellen med Movie databasschemat.
  • Skapa kod för att migrera databasschemat till den nya modellen.

Namnet "Rating" är godtyckligt och används för att namnge migreringsfilen. Det är bra att använda ett beskrivande namn för migreringsfilen.

  1. I PMC anger du följande kommando:

    Update-Database
    

Kommandot Update-Database instruerar ramverket att tillämpa schemaändringarna på databasen och bevara befintliga data.

Ta bort alla poster i databasen, initialiseraren kommer att ladda databasen och inkludera fältet Rating. Borttagning kan göras med borttagningslänkarna i webbläsaren eller från Sql Server Object Explorer (SSOX).

Ett annat alternativ är att ta bort databasen och använda migreringar för att återskapa databasen. Så här tar du bort databasen i SSOX:

  1. Välj databasen i SSOX.

  2. Högerklicka på databasen och välj Ta bort.

  3. Kontrollera Stäng befintliga anslutningar.

  4. Välj OK.

  5. I PMC-uppdaterar du databasen:

    Update-Database
    

Kör appen och kontrollera att du kan skapa, redigera och visa filmer med ett Rating fält. Om databasen inte är seedad anger du en brytpunkt i metoden SeedData.Initialize.

Nästa steg

I det här avsnittet används Entity Framework Code First Migrations för att:

  • Lägg till ett nytt fält i modellen.
  • Migrera den nya fältschemaändringen till databasen.

När du använder EF Code First för att automatiskt skapa och spåra en databas, Code First

  • Lägger till en __EFMigrationsHistory tabell i databasen för att spåra om schemat för databasen är synkroniserat med de modellklasser som den genererades från.
  • Utlöser ett undantag om modellklasserna inte är synkroniserade med databasen.

Automatisk verifiering av att schemat och modellen är synkroniserade gör det enklare att hitta inkonsekventa problem med databaskod.

Lägga till en klassificeringsegenskap i filmmodellen

  1. Öppna filen Models/Movie.cs och lägg till en egenskap för 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. Redigera Pages/Movies/Index.cshtmloch lägg till ett Rating fält:

    @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>
            <label>Title: <input type="text" asp-for="SearchString" /></label>
            <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. Uppdatera följande sidor med ett Rating fält:

Appen fungerar inte förrän databasen har uppdaterats för att inkludera det nya fältet. När du kör appen utan en uppdatering av databasen utlöss en SqlException:

SqlException: Invalid column name 'Rating'.

Undantaget SqlException orsakas av att den uppdaterade filmmodellklassen skiljer sig från schemat för tabellen Film i databasen. Det finns ingen Rating kolumn i databastabellen.

Det finns några metoder för att lösa felet:

  1. Låt Entity Framework automatiskt släppa och återskapa databasen med hjälp av det nya modellklassschemat. Den här metoden är praktisk tidigt i utvecklingscykeln, vilket gör att utvecklare snabbt kan utveckla modellen och databasschemat tillsammans. Nackdelen är att befintliga data i databasen går förlorade. Använd inte den här metoden i en produktionsdatabas! Att ta bort databasen vid schemaändringar och använda en initierare för att automatiskt seeda databasen med testdata är ofta ett produktivt sätt att utveckla en app.
  2. Ändra uttryckligen schemat för den befintliga databasen så att den matchar modellklasserna. Fördelen med den här metoden är att behålla data. Gör den här ändringen antingen manuellt eller genom att skapa ett databasändringsskript.
  3. Använd Code First Migrations för att uppdatera databasschemat.

I den här handledningen ska du använda Code First Migrations.

Uppdatera klassen SeedData så att den ger ett värde för den nya kolumnen. En exempeländring visas nedan, men gör den här ändringen för varje new Movie block.

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

Se den slutförda filen SeedData.cs .

Skapa appen

Tryck på Ctrl+Skift+B

Lägga till en migrering för klassificeringsfältet

  1. På menyn Verktyg väljer du NuGet Package Manager > Package Manager Console.

  2. I PMC anger du följande kommandon:

    Add-Migration Rating
    Update-Database
    

Kommandot Add-Migration instruerar ramverket att:

  • Jämför Movie-modellen med Movie databasschemat.
  • Skapa kod för att migrera databasschemat till den nya modellen.

Namnet "Rating" är godtyckligt och används för att namnge migreringsfilen. Det är bra att använda ett beskrivande namn för migreringsfilen.

Kommandot Update-Database instruerar ramverket att tillämpa schemaändringarna på databasen och bevara befintliga data.

Ta bort alla poster i databasen, initieraren kommer att fylla databasen och inkludera fältet Rating. Borttagning kan göras med borttagningslänkarna i webbläsaren eller från Sql Server Object Explorer (SSOX).

Ett annat alternativ är att ta bort databasen och använda migreringar för att återskapa databasen. Så här tar du bort databasen i SSOX:

  1. Välj databasen i SSOX.

  2. Högerklicka på databasen och välj Ta bort.

  3. Kontrollera Stäng befintliga anslutningar.

  4. Välj OK.

  5. I PMC-uppdaterar du databasen:

    Update-Database
    

Kör appen och kontrollera att du kan skapa, redigera och visa filmer med ett Rating fält. Om databasen inte är seedad anger du en brytpunkt i metoden SeedData.Initialize.

Nästa steg

I det här avsnittet används Entity Framework Code First Migrations för att:

  • Lägg till ett nytt fält i modellen.
  • Migrera den nya fältschemaändringen till databasen.

När du använder EF Code First för att automatiskt skapa och spåra en databas, Code First:

  • Lägger till en __EFMigrationsHistory tabell i databasen för att spåra om schemat för databasen är synkroniserat med de modellklasser som den genererades från.
  • Utlöser ett undantag om modellklasserna inte är synkroniserade med databasen.

Automatisk verifiering av att schemat och modellen är synkroniserade gör det enklare att hitta inkonsekventa problem med databaskod.

Lägga till en klassificeringsegenskap i filmmodellen

  1. Öppna filen Models/Movie.cs och lägg till en egenskap för 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. Redigera Pages/Movies/Index.cshtmloch lägg till ett Rating fält:

    @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>
            <label>Title: <input type="text" asp-for="SearchString" /></label>
            <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. Uppdatera följande sidor med ett Rating fält:

Appen fungerar inte förrän databasen har uppdaterats för att inkludera det nya fältet. När du kör appen utan en uppdatering av databasen utlöss en SqlException:

SqlException: Invalid column name 'Rating'.

Undantaget SqlException orsakas av att den uppdaterade filmmodellklassen skiljer sig från schemat för tabellen Film i databasen. Det finns ingen Rating kolumn i databastabellen.

Det finns några metoder för att lösa felet:

  1. Låt Entity Framework automatiskt släppa och återskapa databasen med hjälp av det nya modellklassschemat. Den här metoden är praktisk tidigt i utvecklingscykeln, vilket gör att utvecklare snabbt kan utveckla modellen och databasschemat tillsammans. Nackdelen är att befintliga data i databasen går förlorade. Använd inte den här metoden i en produktionsdatabas! Att ta bort databasen vid schemaändringar och använda en initierare för att automatiskt seeda databasen med testdata är ofta ett produktivt sätt att utveckla en app.
  2. Ändra uttryckligen schemat för den befintliga databasen så att den matchar modellklasserna. Fördelen med den här metoden är att behålla data. Gör den här ändringen antingen manuellt eller genom att skapa ett databasändringsskript.
  3. Använd Code First Migrations för att uppdatera databasschemat.

I denna handledning använder du Code First Migrations.

Uppdatera klassen SeedData så att den ger ett värde för den nya kolumnen. En exempeländring visas nedan, men gör den här ändringen för varje new Movie block.

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

Se den slutförda filen SeedData.cs .

Skapa appen

Tryck på Ctrl+Skift+B

Lägga till en migrering för klassificeringsfältet

  1. På menyn Verktyg väljer du NuGet Package Manager > Package Manager Console.

  2. I PMC anger du följande kommandon:

    Add-Migration Rating
    Update-Database
    

Kommandot Add-Migration instruerar ramverket att:

  • Jämför Movie-modellen med Movie databasschemat.
  • Skapa kod för att migrera databasschemat till den nya modellen.

Namnet "Rating" är godtyckligt och används för att namnge migreringsfilen. Det är bra att använda ett beskrivande namn för migreringsfilen.

Kommandot Update-Database instruerar ramverket att tillämpa schemaändringarna på databasen och bevara befintliga data.

Ta bort alla poster i databasen, initieraren kommer att förbereda databasen och inkludera fältet Rating. Borttagning kan göras med borttagningslänkarna i webbläsaren eller från Sql Server Object Explorer (SSOX).

Ett annat alternativ är att ta bort databasen och använda migreringar för att återskapa databasen. Så här tar du bort databasen i SSOX:

  1. Välj databasen i SSOX.

  2. Högerklicka på databasen och välj Ta bort.

  3. Kontrollera Stäng befintliga anslutningar.

  4. Välj OK.

  5. I PMC-uppdaterar du databasen:

    Update-Database
    

Kör appen och kontrollera att du kan skapa, redigera och visa filmer med ett Rating fält. Om databasen inte är seedad anger du en brytpunkt i metoden SeedData.Initialize.

Nästa steg

I det här avsnittet används Entity Framework Code First Migrations för att:

  • Lägg till ett nytt fält i modellen.
  • Migrera den nya fältschemaändringen till databasen.

När du använder EF Code First för att automatiskt skapa och spåra en databas, Code First:

  • Lägger till en __EFMigrationsHistory tabell i databasen för att spåra om schemat för databasen är synkroniserat med de modellklasser som den genererades från.
  • Utlöser ett undantag om modellklasserna inte är synkroniserade med databasen.

Automatisk verifiering av att schemat och modellen är synkroniserade gör det enklare att hitta inkonsekventa problem med databaskod.

Lägga till en klassificeringsegenskap i filmmodellen

  1. Öppna filen Models/Movie.cs och lägg till en egenskap för 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. Redigera Pages/Movies/Index.cshtmloch lägg till ett Rating fält:

    @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>
            <label>Title: <input type="text" asp-for="SearchString" /></label>
            <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. Uppdatera följande sidor med ett Rating fält:

Appen fungerar inte förrän databasen har uppdaterats för att inkludera det nya fältet. När du kör appen utan en uppdatering av databasen utlöss en SqlException:

SqlException: Invalid column name 'Rating'.

Undantaget SqlException orsakas av att den uppdaterade filmmodellklassen skiljer sig från schemat för tabellen Film i databasen. Det finns ingen Rating kolumn i databastabellen.

Det finns några metoder för att lösa felet:

  1. Låt Entity Framework automatiskt släppa och återskapa databasen med hjälp av det nya modellklassschemat. Den här metoden är praktisk tidigt i utvecklingscykeln, vilket gör att utvecklare snabbt kan utveckla modellen och databasschemat tillsammans. Nackdelen är att befintliga data i databasen går förlorade. Använd inte den här metoden i en produktionsdatabas! Att ta bort databasen vid schemaändringar och använda en initierare för att automatiskt seeda databasen med testdata är ofta ett produktivt sätt att utveckla en app.
  2. Ändra uttryckligen schemat för den befintliga databasen så att den matchar modellklasserna. Fördelen med den här metoden är att behålla data. Gör den här ändringen antingen manuellt eller genom att skapa ett databasändringsskript.
  3. Använd Code First Migrations för att uppdatera databasschemat.

I den här handledningen använder du Code First Migrations.

Uppdatera klassen SeedData så att den ger ett värde för den nya kolumnen. En exempeländring visas nedan, men gör den här ändringen för varje new Movie block.

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

Se den slutförda filen SeedData.cs.

Skapa lösningen.

Lägga till en migrering för klassificeringsfältet

  1. På menyn Verktyg väljer du NuGet Package Manager > Package Manager Console.

  2. I PMC anger du följande kommandon:

    Add-Migration Rating
    Update-Database
    

Kommandot Add-Migration instruerar ramverket att:

  • Jämför Movie-modellen med Movie databasschemat.
  • Skapa kod för att migrera databasschemat till den nya modellen.

Namnet "Rating" är godtyckligt och används för att namnge migreringsfilen. Det är bra att använda ett beskrivande namn för migreringsfilen.

Kommandot Update-Database instruerar ramverket att tillämpa schemaändringarna på databasen och bevara befintliga data.

Ta bort alla poster i databasen, initieraren kommer att initiera databasen och inkludera fältet Rating. Borttagning kan göras med borttagningslänkarna i webbläsaren eller från Sql Server Object Explorer (SSOX).

Ett annat alternativ är att ta bort databasen och använda migreringar för att återskapa databasen. Så här tar du bort databasen i SSOX:

  1. Välj databasen i SSOX.

  2. Högerklicka på databasen och välj Ta bort.

  3. Kontrollera Stäng befintliga anslutningar.

  4. Välj OK.

  5. I PMC-uppdaterar du databasen:

    Update-Database
    

Kör appen och kontrollera att du kan skapa, redigera och visa filmer med ett Rating fält. Om databasen inte är seedad anger du en brytpunkt i metoden SeedData.Initialize.

Nästa steg

Visa eller ladda ned exempelkod (hur du laddar ned).

I det här avsnittet används Entity Framework Code First Migrations för att:

  • Lägg till ett nytt fält i modellen.
  • Migrera den nya fältschemaändringen till databasen.

När du använder EF Code First för att automatiskt skapa en databas, Code First:

  • Lägger till en __EFMigrationsHistory tabell i databasen för att spåra om schemat för databasen är synkroniserat med de modellklasser som den genererades från.
  • Om modellklasserna inte är synkroniserade med databasen genererar EF ett undantag.

Automatisk verifiering av att schemat och modellen är synkroniserade gör det enklare att hitta inkonsekventa problem med databaskod.

Lägga till en klassificeringsegenskap i filmmodellen

  1. Öppna filen Models/Movie.cs och lägg till en egenskap för 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. Skapa appen.

  3. Redigera Pages/Movies/Index.cshtmloch lägg till ett Rating fält:

    @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>
            <label>Title: <input type="text" asp-for="SearchString" /></label>
            <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. Uppdatera följande sidor med ett Rating fält:

Appen fungerar inte förrän databasen har uppdaterats för att inkludera det nya fältet. När du kör appen utan en uppdatering av databasen utlöss en SqlException:

SqlException: Invalid column name 'Rating'.

Undantaget SqlException orsakas av att den uppdaterade filmmodellklassen skiljer sig från schemat för tabellen Film i databasen. Det finns ingen Rating kolumn i databastabellen.

Det finns några metoder för att lösa felet:

  1. Låt Entity Framework automatiskt släppa och återskapa databasen med hjälp av det nya modellklassschemat. Den här metoden är praktisk tidigt i utvecklingscykeln, så att du snabbt kan utveckla modellen och databasschemat tillsammans. Nackdelen är att du förlorar befintliga data i databasen. Använd inte den här metoden i en produktionsdatabas! Att ta bort databasen vid schemaändringar och använda en initierare för att automatiskt seeda databasen med testdata är ofta ett produktivt sätt att utveckla en app.

  2. Ändra uttryckligen schemat för den befintliga databasen så att den matchar modellklasserna. Fördelen med den här metoden är att behålla data. Gör den här ändringen antingen manuellt eller genom att skapa ett databasändringsskript.

  3. Använd Code First Migrations för att uppdatera databasschemat.

I den här självstudien använder du Code First Migrations.

Uppdatera klassen SeedData så att den ger ett värde för den nya kolumnen. En exempeländring visas nedan, men gör den här ändringen för varje new Movie block.

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

Se den slutförda SeedData.cs filen.

Skapa lösningen.

Lägga till en migrering för klassificeringsfältet

  1. På menyn Verktyg väljer du NuGet Package Manager > Package Manager Console.

  2. I PMC anger du följande kommandon:

    Add-Migration Rating
    Update-Database
    

Kommandot Add-Migration instruerar ramverket att:

  • Jämför Movie-modellen med Movie databasschemat.
  • Skapa kod för att migrera databasschemat till den nya modellen.

Namnet "Rating" är godtyckligt och används för att namnge migreringsfilen. Det är bra att använda ett beskrivande namn för migreringsfilen.

Kommandot Update-Database instruerar ramverket att tillämpa schemaändringarna på databasen och bevara befintliga data.

Ta bort alla poster i databasen, initieraren ska fylla databasen med data och inkludera fältet Rating. Borttagning kan göras med borttagningslänkarna i webbläsaren eller från Sql Server Object Explorer (SSOX).

Ett annat alternativ är att ta bort databasen och använda migreringar för att återskapa databasen. Så här tar du bort databasen i SSOX:

  1. Välj databasen i SSOX.

  2. Högerklicka på databasen och välj Ta bort.

  3. Kontrollera Stäng befintliga anslutningar.

  4. Välj OK.

  5. I PMC-uppdaterar du databasen:

    Update-Database
    

Kör appen och kontrollera att du kan skapa/redigera/visa filmer med ett Rating fält. Om databasen inte är seedad anger du en brytpunkt i metoden SeedData.Initialize.

Nästa steg

Visa eller ladda ned exempelkod (hur du laddar ned).

I det här avsnittet används Entity Framework Code First Migrations för att:

  • Lägg till ett nytt fält i modellen.
  • Migrera den nya fältschemaändringen till databasen.

När du använder EF Code First för att automatiskt skapa en databas, följ dessa steg:

  • Lägger till en __EFMigrationsHistory tabell i databasen för att spåra om schemat för databasen är synkroniserat med de modellklasser som den genererades från.
  • Om modellklasserna inte är synkroniserade med databasen genererar EF ett undantag.

Automatisk verifiering av att schemat och modellen är synkroniserade gör det enklare att hitta inkonsekventa problem med databaskod.

Lägga till en klassificeringsegenskap i filmmodellen

  1. Öppna filen Models/Movie.cs och lägg till en egenskap för 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. Skapa appen.

  3. Redigera Pages/Movies/Index.cshtmloch lägg till ett Rating fält:

    @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>
            <label>Title: <input type="text" asp-for="SearchString" /></label>
            <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. Uppdatera följande sidor med ett Rating fält:

Appen fungerar inte förrän databasen har uppdaterats för att inkludera det nya fältet. När du kör appen utan en uppdatering av databasen utlöss en SqlException:

SqlException: Invalid column name 'Rating'.

Undantaget SqlException orsakas av att den uppdaterade filmmodellklassen skiljer sig från schemat för tabellen Film i databasen. Det finns ingen Rating kolumn i databastabellen.

Det finns några metoder för att lösa felet:

  1. Låt Entity Framework automatiskt släppa och återskapa databasen med hjälp av det nya modellklassschemat. Den här metoden är praktisk tidigt i utvecklingscykeln, så att du snabbt kan utveckla modellen och databasschemat tillsammans. Nackdelen är att du förlorar befintliga data i databasen. Använd inte den här metoden i en produktionsdatabas! Att ta bort databasen vid schemaändringar och använda en initierare för att automatiskt seeda databasen med testdata är ofta ett produktivt sätt att utveckla en app.

  2. Ändra uttryckligen schemat för den befintliga databasen så att den matchar modellklasserna. Fördelen med den här metoden är att behålla data. Gör den här ändringen antingen manuellt eller genom att skapa ett databasändringsskript.

  3. Använd Code First Migrations för att uppdatera databasschemat.

I denna handledning använder du Code First Migrations.

Uppdatera klassen SeedData så att den ger ett värde för den nya kolumnen. En exempeländring visas nedan, men gör den här ändringen för varje new Movie block.

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

Se den slutförda SeedData.cs filen.

Skapa lösningen.

Lägga till en migrering för klassificeringsfältet

  1. På menyn Verktyg väljer du NuGet Package Manager > Package Manager Console.

  2. I PMC anger du följande kommandon:

    Add-Migration Rating
    Update-Database
    

Kommandot Add-Migration instruerar ramverket att:

  • Jämför Movie-modellen med Movie databasschemat.
  • Skapa kod för att migrera databasschemat till den nya modellen.

Namnet "Rating" är godtyckligt och används för att namnge migreringsfilen. Det är bra att använda ett beskrivande namn för migreringsfilen.

Kommandot Update-Database instruerar ramverket att tillämpa schemaändringarna på databasen och bevara befintliga data.

Om du tar bort alla poster i databasen kommer initieraren att fylla databasen och inkludera fältet Rating. Du kan göra detta med borttagningslänkarna i webbläsaren eller från Sql Server Object Explorer (SSOX).

Ett annat alternativ är att ta bort databasen och använda migreringar för att återskapa databasen. Så här tar du bort databasen i SSOX:

  • Välj databasen i SSOX.

  • Högerklicka på databasen och välj Ta bort.

  • Kontrollera Stäng befintliga anslutningar.

  • Välj OK.

  • I PMC-uppdaterar du databasen:

    Update-Database
    

Kör appen och kontrollera att du kan skapa/redigera/visa filmer med ett Rating fält. Om databasen inte är seedad anger du en brytpunkt i metoden SeedData.Initialize.

Nästa steg