添加數據模型類html
右鍵單擊 Models 文件夾,而後單擊「添加」 > 「類」。 將類命名「Movie」。
向 Movie 類添加如下屬性:數據庫
using System;
using System.ComponentModel.DataAnnotations;json
namespace MvcMovie.Models
{
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }瀏覽器
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
}cookie
Movie 類包含:架構
數據庫須要 Id 字段以獲取主鍵。
[DataType(DataType.Date)]:DataType 屬性指定數據的類型 (Date)。 經過此特性:
用戶無需在數據字段中輸入時間信息。
僅顯示日期,而非時間信息。app
搭建「電影」模型的基架框架
基架工具將生成頁面,用於對「電影」模型執行建立、讀取、更新和刪除 (CRUD) 操做。
在解決方案資源管理器中,右鍵單擊「Controllers」文件夾 >「添加」>「新搭建基架的項目」。
在「添加基架」對話框中,選擇「包含視圖的 MVC 控制器(使用 Entity Framework)」>「添加」。
填寫「添加控制器」對話框:async
模型類:Movie (MvcMovie.Models)
數據上下文類:選擇 + 圖標並添加默認的 MvcMovie.Models.MvcMovieContext
視圖:將每一個選項保持爲默認選中狀態
控制器名稱:保留默認的 MoviesController
選擇「添加」函數
Visual Studio 將建立:
Entity Framework Core 數據庫上下文類 (Data/MvcMovieContext.cs)
電影控制器 (Controllers/MoviesController.cs)
「建立」、「刪除」、「詳細信息」、「編輯」和「索引」頁面的 Razor 視圖文件 (Views/Movies/*.cshtml)
自動建立數據庫上下文和 CRUD(建立、讀取、更新和刪除)操做方法和視圖的過程稱爲「搭建基架」。
初始遷移
添加初始遷移。
使用初始遷移來更新數據庫。
1.從「工具」菜單中,選擇「NuGet 包管理器」 > 「包管理器控制檯」(PMC)。
2.在 PMC 中,輸入如下命令:
Add-Migration Initial
Update-Database
Add-Migration 命令生成用於建立初始數據庫架構的代碼。
數據庫架構基於在 MvcMovieContext 類中(位於 Data/MvcMovieContext.cs 文件中)中指定的模型。 Initial 參數是遷移名稱。
可使用任何名稱,可是按照慣例,會使用可說明遷移的名稱。 有關更多信息,請參見教程:使用遷移功能 - ASP.NET MVC 和 EF Core。
Update-Database 命令在用於建立數據庫的 Migrations/{time-stamp}_InitialCreate.cs 文件中運行 Up 方法。
檢查經過依賴關係注入註冊的上下文
ASP.NET Core 經過依賴關係注入 (DI) 生成。 服務(例如 EF Core 數據庫上下文)在應用程序啓動期間經過 DI 註冊。
須要這些服務(如 Razor 頁面)的組件經過構造函數提供相應服務。
基架工具自動建立數據庫上下文並將其註冊到 DI 容器。
咱們來研究如下 Startup.ConfigureServices 方法。 基架添加了突出顯示的行:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies
// is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));\\
}
MvcMovieContext 爲 Movie 模型協調 EF Core 功能(建立、讀取、更新、刪除等)。 數據上下文 (MvcMovieContext)
派生自 Microsoft.EntityFrameworkCore.DbContext。 數據上下文指定數據模型中包含哪些實體:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace MvcMovie.Models
{
public class MvcMovieContext : DbContext
{
public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
: base(options)
{
}
public DbSet<MvcMovie.Models.Movie> Movie { get; set; }
}
}
前面的代碼爲實體集建立 DbSet<Movie> 屬性。 在實體框架術語中,實體集一般與數據表相對應。 實體對應表中的行。
經過調用 DbContextOptions 對象中的一個方法將鏈接字符串名稱傳遞到上下文。 進行本地開發時, ASP.NET Core 配置系統
在 appsettings.json 文件中讀取數據庫鏈接字符串。
測試應用
運行應用並將 /Movies 追加到瀏覽器中的 URL (http://localhost:port/movies)。
若是收到以下所示數據庫異常:缺乏遷移步驟。
SqlException: Cannot open database "MvcMovieContext-GUID" requested by the login. The login failed.
Login failed for user 'User-name'.
檢查 Startup 類:ConfigureServices方法
services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
上面突出顯示的代碼顯示了要添加到依賴關係注入容器的電影數據庫上下文:
services.AddDbContext<MvcMovieContext>(options => 指定要使用的數據庫和鏈接字符串。
=> 是 lambda 運算符
打開 Controllers/MoviesController.cs 文件並檢查構造函數:
public class MoviesController : Controller
{
private readonly MvcMovieContext _context;
public MoviesController(MvcMovieContext context)
{
_context = context;
}
構造函數使用依賴關係注入將數據庫上下文 (MvcMovieContext) 注入到控制器中。 數據庫上下文將在控制器中的每一個 CRUD 方法中使用。
強類型模型和 @model 關鍵詞
MVC 還提供將強類型模型對象傳遞給視圖的功能。 憑藉此強類型方法可更好地對代碼進行編譯時檢查。 基架機制在建立方法和視圖時,
經過 MoviesController 類和視圖使用了此方法(即傳遞強類型模型)。
檢查 Controllers/MoviesController.cs 文件中生成的 Details 方法:
// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
id 參數一般做爲路由數據傳遞。 例如 https://localhost:5001/movies/details/1 的設置以下:
控制器被設置爲 movies 控制器(第一個 URL 段)。
操做被設置爲 details(第二個 URL 段)。
ID 被設置爲 1(最後一個 URL 段)。
還可使用查詢字符串傳入 id,以下所示:
https://localhost:5001/movies/details?id=1
在未提供 ID 值的狀況下,id 參數可定義爲能夠爲 null 的類型 (int?)。
Lambda 表達式會被傳入 FirstOrDefaultAsync 以選擇與路由數據或查詢字符串值相匹配的電影實體。
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
若是找到了電影,Movie 模型的實例則會被傳遞到 Details 視圖:
return View(movie);
檢查 Views/Movies/Details.cshtml 文件的內容:
@model MvcMovie.Models.Movie
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>Movie</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Title)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Title)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.ReleaseDate)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.ReleaseDate)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Genre)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Genre)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Price)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Price)
</dd>
</dl>
</div>
<div>
<a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
<a asp-action="Index">Back to List</a>
</div>
經過將 @model 語句包括在視圖文件的頂端,能夠指定視圖指望的對象類型。
建立電影控制器時,會自動在 Details.cshtml 文件的頂端包括如下 @model 語句:
@model MvcMovie.Models.Movie
此 @model 指令使你可以使用強類型的 Model 對象訪問控制器傳遞給視圖的電影。 例如,在 Details.cshtml 視圖中,
代碼經過強類型的 Model 對象將每一個電影字段傳遞給 DisplayNameFor 和 DisplayForHTML 幫助程序。
Create 和 Edit 方法以及視圖也傳遞一個 Movie 模型對象。
檢查電影控制器中的 Index.cshtml 視圖和 Index 方法。 請注意代碼在調用 View 方法時是如何建立 List 對象的。
代碼將此 Movies 列表從 Index 操做方法傳遞給視圖:
// GET: Movies
public async Task<IActionResult> Index()
{
return View(await _context.Movie.ToListAsync());
}
建立電影控制器時,基架會自動在 Index.cshtml 文件的頂端包含如下 @model 語句:
@model IEnumerable<MvcMovie.Models.Movie>
@model 指令使你可以使用強類型的 Model 對象訪問控制器傳遞給視圖的電影列表。 例如,在 Index.cshtml 視圖中,
代碼使用 foreach 語句經過強類型 Model 對象對電影進行循環遍歷:
@model IEnumerable<MvcMovie.Models.Movie> \\
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {\\
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)\\
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)\\
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)\\
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)\\
</td>
<td>
<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>
由於 Model 對象爲強類型(做爲 IEnumerable<Movie> 對象),所以循環中的每一個項都被類型化爲 Movie。 除其餘優勢以外,這意味着可對代碼進行編譯時檢查: