共用方式為


第 8 部分,將欄位新增至 ASP.NET Core MVC 應用程式

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支援原則。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

作者:Rick Anderson

在本章節中,會使用 Entity Framework 移轉來:

  • 在模型中新增一個欄位。
  • 將新的欄位移轉至資料庫。

當 Entity Framework (EF) 用來從模型類別自動建立資料庫時:

  • 將資料表新增至資料庫,以追蹤資料庫的結構描述。
  • 系統會驗證資料庫是否與產生它的模型類別同步。 如果未同步,EF 會擲回例外狀況。 這可讓您更輕鬆地找出不一致的資料庫/程式碼問題。

將 Rating 屬性新增至電影模型

Rating 屬性新增至 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; }
}

建置應用程式

按下 Ctrl+Shift+B

因為您已將欄位新增至 Movie 類別,所以需要更新繫結清單,以便包含這個新屬性。 在 MoviesController.cs 中,更新 CreateEdit 這兩個動作方法的 [Bind] 屬性 (attribute),以包括 Rating 屬性 (property):

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

更新檢視範本,以便在瀏覽器檢視中顯示、建立和編輯新的 Rating 屬性。

編輯 /Views/Movies/Index.cshtml 檔案,並新增 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>

使用 Rating 欄位更新 /Views/Movies/Create.cshtml

您可以複製/貼上前一個「表單群組」,讓 IntelliSense 協助您更新這些欄位。 IntelliSense 會使用標記協助程式

在檢視的第二個 Label 項目中,開發人員已針對 asp-for 屬性值鍵入字母 R。IntelliSense 的操作功能表會顯示可用的欄位,包括 Rating (清單中已自動反白顯示)。當開發人員按一下欄位,或按下鍵盤上的 Enter 鍵時,即會將值設為 Rating。

Rating 屬性新增至其餘的 Create.cshtmlDelete.cshtmlDetails.cshtmlEdit.cshtml 檢視範本。

更新 SeedData 類別,使其提供新資料行的值。 範例變更如下所示,但您會想要為每個 new Movie 進行這項變更。

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

在更新資料庫以包含新欄位之前,應用程式無法運作。 如果立即執行,則會擲回下列 SqlException

SqlException: Invalid column name 'Rating'.

此錯誤是因為更新的電影模型類別,不同於現有資料庫之電影資料表的結構描述。 (資料庫資料表中沒有任何 Rating 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在開發週期早期,當您在測試資料庫上進行開發時,這個方法會很方便;其可讓您一併調整模型和資料庫結構描述,更加快速。 不過,它的缺點是您會遺失資料庫中現有的資料 — 因此您不會想在實際執行的資料庫上使用這種方法! 使用初始設定式將測試資料自動植入資料庫,通常是開發應用程式的有效方式。 這是早期開發和使用 SQLite 時的好方法。

  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

  3. 使用 Entity Framework 移轉來更新資料庫結構描述。

本教學課程會使用 Entity Framework 移轉。

從 [工具] 功能表中,選取 [NuGet 套件管理員] > [套件管理員主控台]

PMC 功能表

在 [套件管理器主控台] 中,輸入下列命令:

Add-Migration Rating

Add-Migration 命令會告知移轉架構,檢查目前的 Movie 模型與目前的 Movie 資料庫結構描述,並建立必要的程式碼以將資料庫移轉至新的模型。

"Rating" 是用來命名移轉檔案的任意名稱。 建議您針對移轉檔案使用有意義的名稱,更加實用。

如果刪除資料庫中的所有記錄,初始化方法會將內容植入資料庫,並包含 Rating 欄位。

在 [套件管理器主控台] 中,輸入下列命令:

Update-Database

「Update-Database」命令會在尚未套用的移轉中執行「Up」方法。

執行應用程式,並驗證您可以使用 Rating 欄位建立、編輯和顯示電影。

在本節中,您會使用 Entity Framework Code First 移轉:

  • 在模型中新增一個欄位。
  • 將新的欄位移轉至資料庫。

使用 EF Code First 自動建立資料庫時,Code First 會:

  • 將資料表新增至資料庫,以追蹤資料庫的結構描述。
  • 驗證資料庫與其產生來源的模型類別同步。 如果未同步,EF 會擲回例外狀況。 這可讓您更輕鬆地找出不一致的資料庫/程式碼問題。

將 Rating 屬性新增至電影模型

Rating 屬性新增至 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; }
}

建置應用程式

按下 Ctrl+Shift+B

因為您已將欄位新增至 Movie 類別,所以需要更新繫結清單,以便包含這個新屬性。 在 MoviesController.cs 中,更新 CreateEdit 這兩個動作方法的 [Bind] 屬性 (attribute),以包括 Rating 屬性 (property):

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

更新檢視範本,以便在瀏覽器檢視中顯示、建立和編輯新的 Rating 屬性。

編輯 /Views/Movies/Index.cshtml 檔案,並新增 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>

使用 Rating 欄位更新 /Views/Movies/Create.cshtml

您可以複製/貼上前一個「表單群組」,讓 IntelliSense 協助您更新這些欄位。 IntelliSense 會使用標記協助程式

在檢視的第二個 Label 項目中,開發人員已針對 asp-for 屬性值鍵入字母 R。IntelliSense 的操作功能表會顯示可用的欄位,包括 Rating (清單中已自動反白顯示)。當開發人員按一下欄位,或按下鍵盤上的 Enter 鍵時,即會將值設為 Rating。

更新其餘的範本。

更新 SeedData 類別,使其提供新資料行的值。 範例變更如下所示,但您會想要為每個 new Movie 進行這項變更。

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

在更新資料庫以包含新欄位之前,應用程式無法運作。 如果立即執行,則會擲回下列 SqlException

SqlException: Invalid column name 'Rating'.

此錯誤是因為更新的電影模型類別,不同於現有資料庫之電影資料表的結構描述。 (資料庫資料表中沒有任何 Rating 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在開發週期早期,當您在測試資料庫上進行開發時,這個方法會很方便;其可讓您一併調整模型和資料庫結構描述,更加快速。 不過,它的缺點是您會遺失資料庫中現有的資料 — 因此您不會想在實際執行的資料庫上使用這種方法! 使用初始設定式將測試資料自動植入資料庫,通常是開發應用程式的有效方式。 這是早期開發和使用 SQLite 時的好方法。

  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

  3. 使用 Code First 移轉來更新資料庫結構描述。

在本教學課程中,請使用 Code First 移轉。

從 [工具] 功能表中,選取 [NuGet 套件管理員] > [套件管理員主控台]

PMC 功能表

在 PMC 中,輸入下列命令:

Add-Migration Rating
Update-Database

Add-Migration 命令會告知移轉架構,檢查目前的 Movie 模型與目前的 Movie 資料庫結構描述,並建立必要的程式碼以將資料庫移轉至新的模型。

"Rating" 是用來命名移轉檔案的任意名稱。 建議您針對移轉檔案使用有意義的名稱,更加實用。

如果刪除資料庫中的所有記錄,初始化方法會將內容植入資料庫,並包含 Rating 欄位。

執行應用程式,並驗證您可以使用 Rating 欄位建立、編輯和顯示電影。

在本節中,您會使用 Entity Framework Code First 移轉:

  • 在模型中新增一個欄位。
  • 將新的欄位移轉至資料庫。

使用 EF Code First 自動建立資料庫時,Code First 會:

  • 將資料表新增至資料庫,以追蹤資料庫的結構描述。
  • 驗證資料庫與其產生來源的模型類別同步。 如果未同步,EF 會擲回例外狀況。 這可讓您更輕鬆地找出不一致的資料庫/程式碼問題。

將 Rating 屬性新增至電影模型

Rating 屬性新增至 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; }
}

建置應用程式

按下 Ctrl+Shift+B

因為您已將欄位新增至 Movie 類別,所以需要更新繫結清單,以便包含這個新屬性。 在 MoviesController.cs 中,更新 CreateEdit 這兩個動作方法的 [Bind] 屬性 (attribute),以包括 Rating 屬性 (property):

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

更新檢視範本,以便在瀏覽器檢視中顯示、建立和編輯新的 Rating 屬性。

編輯 /Views/Movies/Index.cshtml 檔案,並新增 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>

使用 Rating 欄位更新 /Views/Movies/Create.cshtml

您可以複製/貼上前一個「表單群組」,讓 IntelliSense 協助您更新這些欄位。 IntelliSense 會使用標記協助程式

在檢視的第二個 Label 項目中,開發人員已針對 asp-for 屬性值鍵入字母 R。IntelliSense 的操作功能表會顯示可用的欄位,包括 Rating (清單中已自動反白顯示)。當開發人員按一下欄位,或按下鍵盤上的 Enter 鍵時,即會將值設為 Rating。

更新其餘的範本。

更新 SeedData 類別,使其提供新資料行的值。 範例變更如下所示,但您會想要為每個 new Movie 進行這項變更。

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

在更新資料庫以包含新欄位之前,應用程式無法運作。 如果立即執行,則會擲回下列 SqlException

SqlException: Invalid column name 'Rating'.

此錯誤是因為更新的電影模型類別,不同於現有資料庫之電影資料表的結構描述。 (資料庫資料表中沒有任何 Rating 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在開發週期早期,當您在測試資料庫上進行開發時,這個方法會很方便;其可讓您一併調整模型和資料庫結構描述,更加快速。 不過,它的缺點是您會遺失資料庫中現有的資料 — 因此您不會想在實際執行的資料庫上使用這種方法! 使用初始設定式將測試資料自動植入資料庫,通常是開發應用程式的有效方式。 這是早期開發和使用 SQLite 時的好方法。

  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

  3. 使用 Code First 移轉來更新資料庫結構描述。

在本教學課程中,請使用 Code First 移轉。

從 [工具] 功能表中,選取 [NuGet 套件管理員] > [套件管理員主控台]

PMC 功能表

在 PMC 中,輸入下列命令:

Add-Migration Rating
Update-Database

Add-Migration 命令會告知移轉架構,檢查目前的 Movie 模型與目前的 Movie 資料庫結構描述,並建立必要的程式碼以將資料庫移轉至新的模型。

"Rating" 是用來命名移轉檔案的任意名稱。 建議您針對移轉檔案使用有意義的名稱,更加實用。

如果刪除資料庫中的所有記錄,初始化方法會將內容植入資料庫,並包含 Rating 欄位。

執行應用程式,並驗證您可以使用 Rating 欄位建立、編輯和顯示電影。

在本節中,您會使用 Entity Framework Code First 移轉:

  • 在模型中新增一個欄位。
  • 將新的欄位移轉至資料庫。

使用 EF Code First 自動建立資料庫時,Code First 會:

  • 將資料表新增至資料庫,以追蹤資料庫的結構描述。
  • 驗證資料庫與其產生來源的模型類別同步。 如果未同步,EF 會擲回例外狀況。 這可讓您更輕鬆地找出不一致的資料庫/程式碼問題。

將 Rating 屬性新增至電影模型

Rating 屬性新增至 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; }
    }
}

建置應用程式

Ctrl+Shift+B

因為您已將欄位新增至 Movie 類別,所以需要更新繫結清單,以便包含這個新屬性。 在 MoviesController.cs 中,更新 CreateEdit 這兩個動作方法的 [Bind] 屬性 (attribute),以包括 Rating 屬性 (property):

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

更新檢視範本,以便在瀏覽器檢視中顯示、建立和編輯新的 Rating 屬性。

編輯 /Views/Movies/Index.cshtml 檔案,並新增 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>

使用 Rating 欄位更新 /Views/Movies/Create.cshtml

您可以複製/貼上前一個「表單群組」,讓 IntelliSense 協助您更新這些欄位。 IntelliSense 會使用標記協助程式

在檢視的第二個 Label 項目中,開發人員已針對 asp-for 屬性值鍵入字母 R。IntelliSense 的操作功能表會顯示可用的欄位,包括 Rating (清單中已自動反白顯示)。當開發人員按一下欄位,或按下鍵盤上的 Enter 鍵時,即會將值設為 Rating。

更新其餘的範本。

更新 SeedData 類別,使其提供新資料行的值。 範例變更如下所示,但您會想要為每個 new Movie 進行這項變更。

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

在更新資料庫以包含新欄位之前,應用程式無法運作。 如果立即執行,則會擲回下列 SqlException

SqlException: Invalid column name 'Rating'.

此錯誤是因為更新的電影模型類別,不同於現有資料庫之電影資料表的結構描述。 (資料庫資料表中沒有任何 Rating 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在開發週期早期,當您在測試資料庫上進行開發時,這個方法會很方便;其可讓您一併調整模型和資料庫結構描述,更加快速。 不過,它的缺點是您會遺失資料庫中現有的資料 — 因此您不會想在實際執行的資料庫上使用這種方法! 使用初始設定式將測試資料自動植入資料庫,通常是開發應用程式的有效方式。 這是早期開發和使用 SQLite 時的好方法。

  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

  3. 使用 Code First 移轉來更新資料庫結構描述。

在本教學課程中,請使用 Code First 移轉。

從 [工具] 功能表中,選取 [NuGet 套件管理員] > [套件管理員主控台]

PMC 功能表

在 PMC 中,輸入下列命令:

Add-Migration Rating
Update-Database

Add-Migration 命令會告知移轉架構,檢查目前的 Movie 模型與目前的 Movie 資料庫結構描述,並建立必要的程式碼以將資料庫移轉至新的模型。

"Rating" 是用來命名移轉檔案的任意名稱。 建議您針對移轉檔案使用有意義的名稱,更加實用。

如果刪除資料庫中的所有記錄,初始化方法會將內容植入資料庫,並包含 Rating 欄位。

執行應用程式,並驗證您可以使用 Rating 欄位建立、編輯和顯示電影。

在本節中,您會使用 Entity Framework Code First 移轉:

  • 在模型中新增一個欄位。
  • 將新的欄位移轉至資料庫。

使用 EF Code First 自動建立資料庫時,Code First 會:

  • 將資料表新增至資料庫,以追蹤資料庫的結構描述。
  • 驗證資料庫與其產生來源的模型類別同步。 如果未同步,EF 會擲回例外狀況。 這可讓您更輕鬆地找出不一致的資料庫/程式碼問題。

將 Rating 屬性新增至電影模型

Rating 屬性新增至 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; }
    }
}

建置應用程式

Ctrl+Shift+B

因為您已將欄位新增至 Movie 類別,所以需要更新繫結清單,以便包含這個新屬性。 在 MoviesController.cs 中,更新 CreateEdit 這兩個動作方法的 [Bind] 屬性 (attribute),以包括 Rating 屬性 (property):

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

更新檢視範本,以便在瀏覽器檢視中顯示、建立和編輯新的 Rating 屬性。

編輯 /Views/Movies/Index.cshtml 檔案,並新增 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>

使用 Rating 欄位更新 /Views/Movies/Create.cshtml

您可以複製/貼上前一個「表單群組」,讓 IntelliSense 協助您更新這些欄位。 IntelliSense 會使用標記協助程式

在檢視的第二個 Label 項目中,開發人員已針對 asp-for 屬性值鍵入字母 R。IntelliSense 的操作功能表會顯示可用的欄位,包括 Rating (清單中已自動反白顯示)。當開發人員按一下欄位,或按下鍵盤上的 Enter 鍵時,即會將值設為 Rating。

更新其餘的範本。

更新 SeedData 類別,使其提供新資料行的值。 範例變更如下所示,但您會想要為每個 new Movie 進行這項變更。

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

在更新資料庫以包含新欄位之前,應用程式無法運作。 如果立即執行,則會擲回下列 SqlException

SqlException: Invalid column name 'Rating'.

此錯誤是因為更新的電影模型類別,不同於現有資料庫之電影資料表的結構描述。 (資料庫資料表中沒有任何 Rating 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在開發週期早期,當您在測試資料庫上進行開發時,這個方法會很方便;其可讓您一併調整模型和資料庫結構描述,更加快速。 不過,它的缺點是您會遺失資料庫中現有的資料 — 因此您不會想在實際執行的資料庫上使用這種方法! 使用初始設定式將測試資料自動植入資料庫,通常是開發應用程式的有效方式。 這是早期開發和使用 SQLite 時的好方法。

  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

  3. 使用 Code First 移轉來更新資料庫結構描述。

在本教學課程中,請使用 Code First 移轉。

從 [工具] 功能表中,選取 [NuGet 套件管理員] > [套件管理員主控台]

PMC 功能表

在 PMC 中,輸入下列命令:

Add-Migration Rating
Update-Database

Add-Migration 命令會告知移轉架構,檢查目前的 Movie 模型與目前的 Movie 資料庫結構描述,並建立必要的程式碼以將資料庫移轉至新的模型。

"Rating" 是用來命名移轉檔案的任意名稱。 建議您針對移轉檔案使用有意義的名稱,更加實用。

如果刪除資料庫中的所有記錄,初始化方法會將內容植入資料庫,並包含 Rating 欄位。

執行應用程式,並驗證您可以使用 Rating 欄位建立、編輯和顯示電影。

在本節中,您會使用 Entity Framework Code First 移轉:

  • 在模型中新增一個欄位。
  • 將新的欄位移轉至資料庫。

使用 EF Code First 自動建立資料庫時,Code First 會:

  • 將資料表新增至資料庫,以追蹤資料庫的結構描述。
  • 驗證資料庫與其產生來源的模型類別同步。 如果未同步,EF 會擲回例外狀況。 這可讓您更輕鬆地找出不一致的資料庫/程式碼問題。

將 Rating 屬性新增至電影模型

Rating 屬性新增至 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; }
    }
}

建置應用程式

Ctrl+Shift+B

因為您已將欄位新增至 Movie 類別,所以需要更新繫結清單,以便包含這個新屬性。 在 MoviesController.cs 中,更新 CreateEdit 這兩個動作方法的 [Bind] 屬性 (attribute),以包括 Rating 屬性 (property):

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

更新檢視範本,以便在瀏覽器檢視中顯示、建立和編輯新的 Rating 屬性。

編輯 /Views/Movies/Index.cshtml 檔案,並新增 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>

使用 Rating 欄位更新 /Views/Movies/Create.cshtml

您可以複製/貼上前一個「表單群組」,讓 IntelliSense 協助您更新這些欄位。 IntelliSense 會使用標記協助程式

在檢視的第二個 Label 項目中,開發人員已針對 asp-for 屬性值鍵入字母 R。IntelliSense 的操作功能表會顯示可用的欄位,包括 Rating (清單中已自動反白顯示)。當開發人員按一下欄位,或按下鍵盤上的 Enter 鍵時,即會將值設為 Rating。

更新其餘的範本。

更新 SeedData 類別,使其提供新資料行的值。 範例變更如下所示,但您會想要為每個 new Movie 進行這項變更。

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

在更新資料庫以包含新欄位之前,應用程式無法運作。 如果立即執行,則會擲回下列 SqlException

SqlException: Invalid column name 'Rating'.

此錯誤是因為更新的電影模型類別,不同於現有資料庫之電影資料表的結構描述。 (資料庫資料表中沒有任何 Rating 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在開發週期早期,當您在測試資料庫上進行開發時,這個方法會很方便;其可讓您一併調整模型和資料庫結構描述,更加快速。 不過,它的缺點是您會遺失資料庫中現有的資料 — 因此您不會想在實際執行的資料庫上使用這種方法! 使用初始設定式將測試資料自動植入資料庫,通常是開發應用程式的有效方式。 這是早期開發和使用 SQLite 時的好方法。

  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

  3. 使用 Code First 移轉來更新資料庫結構描述。

在本教學課程中,請使用 Code First 移轉。

從 [工具] 功能表中,選取 [NuGet 套件管理員] > [套件管理員主控台]

PMC 功能表

在 PMC 中,輸入下列命令:

Add-Migration Rating
Update-Database

Add-Migration 命令會告知移轉架構,檢查目前的 Movie 模型與目前的 Movie 資料庫結構描述,並建立必要的程式碼以將資料庫移轉至新的模型。

"Rating" 是用來命名移轉檔案的任意名稱。 建議您針對移轉檔案使用有意義的名稱,更加實用。

如果刪除資料庫中的所有記錄,初始化方法會將內容植入資料庫,並包含 Rating 欄位。

執行應用程式,並驗證您可以使用 Rating 欄位建立、編輯和顯示電影。