008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一個model (模型)】

 

索引:html

目錄索引web

Adding a model to an ASP.NET Core MVC app
在 asp.net core mvc 中添加一個model (模型)
2017-3-30 8 分鐘閱讀時長
本文內容
1. Add a data model class
添加一個數據模型類
2. Scaffolding a controller
控制器基架
3. Add EF tooling and perform initial migration
添加EF工具並作基本遷移
4. Test the app
測試應用
5. Dependency Injection
依賴注入
6. Strongly typed models and the @model keyword
強類型模型與 @model 關鍵字
7. Additional resources
附加資源
By Rick Anderson and Tom Dykstra
In this section you'll add some classes for managing movies in a database.
在本節,咱們將添加一些類用於在db中管理 movies。
These classes will be the "Model" part of the MVC app.
這些類是 MVC 中的 Model部分。
You’ll use these classes with the Entity Framework Core (EF Core) to work with a database.
咱們將使用 EF core 在DB上操做這些類與數據。
EF Core is an object-relational mapping (ORM) framework that simplifies the data-access code that you have to write.
EF core 是一個對象關係映射框架,能夠簡化操做數據庫所須要寫的代碼及代碼量。
For this tutorial you'll use SQLite, but EF Core supports many database engines.
本教程中咱們使用 SQLite數據庫,固然EF core 支持不少種數據庫。
The model classes you'll create are known as POCO classes (from "plain-old CLR objects") because they don't have any dependency on EF Core.
咱們將建立一些簡單模型類,由於他們對EF core 沒有任何依賴。
They just define the properties of the data that will be stored in the database.
僅在類中定義DB中所要存儲的字段屬性。
In this tutorial you'll write the model classes first, and EF Core will create the database.
在本教程中,咱們採用 Code First 模式,先定義類,再用EF core 建立DB.
An alternate approach not covered here is to generate model classes from an already-existing database.
另外一種作法是DB First 模式,用一個已存在的DB自動生成數據模型類。
For information about that approach, see ASP.NET Core - Existing Database.
查看文章 ASP.NET Core - Existing Database. 以獲取更多關於DB First 模式的信息。
Add a data model class
添加一個數據模型類
In Solution Explorer, right click the MvcMovie project > Add > New Folder. Name the folder Models.
在解決方案資源管理器中,右擊 MvcMovie 項目 > Add > New Folder 菜單。並命名文件夾爲 Models 。
Right click the Models folder > Add > Class. Name the class Movie and add the following properties:
右擊 Models 文件夾 > Add > Class 菜單。命名類的名字爲Movie ,並在其中添加以下的屬性代碼:數據庫

 

 1 using System;
 2 
 3 namespace MvcMovie.Models
 4 {
 5     public class Movie
 6     {
 7         public int ID { get; set; }
 8         public string Title { get; set; }
 9         public DateTime ReleaseDate { get; set; }
10         public string Genre { get; set; }
11         public decimal Price { get; set; }
12     }
13 }
C# code

 

The ID field is required by the database for the primary key.
ID 字段是數據庫要求必須有的主鍵。
Build the project to verify you don't have any errors. You now have a Model in your MVC app.
編譯項目檢查確保沒有錯誤。如今咱們在程序中就有了MVC中的M。
Scaffolding a controller
控制器基架
In Solution Explorer, right-click the Controllers folder > Add > Controller.
在解決方案資源管理器中,右擊 Controllers 文件夾,選擇 > Add > Controller 菜單。express

In the Add MVC Dependencies dialog, select Minimal Dependencies, and select Add.
在Add MVC Dependencies 對話框中,選擇 Minimal Dependencies 並點擊Add 按鈕。bash

Visual Studio adds the dependencies needed to scaffold a controller, but the controller itself is not created.
VS會添加控制器基架所需的依賴項,但控制器如今尚未被建立。
The next invoke of > Add > Controller creates the controller.
繼續點擊 > Add > Controller 菜單,會添加一個控制器。
In Solution Explorer, right-click the Controllers folder > Add > Controller.
在解決方案資源管理器中,右擊 Controllers 文件夾並選擇> Add > Controller 菜單。服務器

In the Add Scaffold dialog, tap MVC Controller with views, using Entity Framework > Add.
在 Add Scaffold 對話框中,點擊 MVC Controller with views, using Entity Framework 選項並點擊Add 按鈕。mvc

Complete the Add Controller dialog:
完成 Add Controller 對話框:
• Model class: Movie (MvcMovie.Models)
Model class :Movie (MvcMovie.Models)(前邊兒添加的模型類)
• Data context class: Select the + icon and add the default MvcMovie.Models.MvcMovieContext
Data context class :點擊 + 按鈕並添加默認的 MvcMovie.Models.MvcMovieContext 。app

• Views: Keep the default of each option checked
Views:保持默認的選項選擇狀態
• Controller name: Keep the default MoviesController
Controller name:保持默認的名字 MoviesController 。
• Tap Add
點擊 Add 按鈕。框架

Visual Studio creates:
VS將會建立以下項:
• An Entity Framework Core database context class (Data/MvcMovieContext.cs)
一個 EF Core 數據上下文類:Data/MvcMovieContext.cs
• A movies controller (Controllers/MoviesController.cs)
一個控制器類:Controllers/MoviesController.cs
• Razor view files for Create, Delete, Details, Edit and Index pages (Views/Movies/\.cshtml*)
CRUD的視圖文件:Views/Movies/\.cshtml*
The automatic creation of the database context and CRUD (create, read, update, and delete) action methods and views is known as scaffolding.
自動建立 DB上下文類,CRUD 控制器 方法及相應視圖的工具是一個 被稱爲基架。
You'll soon have a fully functional web application that lets you manage a movie database.
你立刻就會有一個完整功能的web應用,可讓你管理一個 movie DB。
If you run the app and click on the Mvc Movie link, you'll get an error similar to the following:
若是你運行應用並點擊 Mvc Movie 連接,你會看到以下一個錯誤提示:asp.net

An unhandled exception occurred while processing the request.
SqlException: Cannot open database "MvcMovieContext-<GUID removed>" 
requested by the login. The login failed.
Login failed for user Rick
Error txt

You need to create the database, and you'll use the EF Core Migrations feature to do that.
你須要建立一個DB,咱們將用EF Core的Migrations 特性來實現。
Migrations lets you create a database that matches your data model and update the database schema when your data model changes.
Migrations 特性可讓你由項目中的Models建立一個DB,而且當model變化時會將變化同步到DB結構中。
Add EF tooling and perform initial migration
添加EF工具並執行初始化遷移
In this section you'll use the Package Manager Console (PMC) to:
在本節,咱們將使用包管理控制檯:
• Add the Entity Framework Core Tools package. This package is required to add migrations and update the database.
添加 EF core 工具包。這個包要求有migrations 及更新 db。
• Add an initial migration.
添加一個初始化的migration
• Update the database with the initial migration.
用初始化的migration 更新數據庫。
From the Tools menu, select NuGet Package Manager > Package Manager Console.
在Tools 菜單,選擇 NuGet Package Manager > Package Manager Console 菜單:

In the PMC, enter the following commands:
在 PMC 命令板上,輸入下面的命令:

Install-Package Microsoft.EntityFrameworkCore.Tools
Add-Migration Initial
Update-Database
PMC bash

The Add-Migration command creates code to create the initial database schema.
Add-Migration 命令生成了初始化db結構的代碼。
The schema is based on the model specified in the DbContext(In the *Data/MvcMovieContext.cs file).
Db結構 基於專門建立的 DbContext 模型類。
The Initialargument is used to name the migrations. You can use any name, but by convention you choose a name that describes the migration.
Initial 參數用於命名migrations 。你能夠在這裏使用任何名字,可是習慣上要使用一個能夠描述 migration 的名字。
See Introduction to migrations for more information.
查看 Introduction to migrations 能夠得到更多信息。
The Update-Database command runs the Up method in the Migrations/<time-stamp>_InitialCreate.csfile, which creates the database.
Update-Database 命令執行了 Migrations/<time-stamp>_InitialCreate.csfile 文件中的 Up 方法建立DB。
Test the app
測試應用
• Run the app and tap the Mvc Movie link.
運行應用並點擊 Mvc Movie 連接。
• Tap the Create New link and create a movie.
點擊 Create New 連接並建立一條電影。

• You may not be able to enter decimal points or commas in the Price field.
你可能不能在 Price 字段裏輸入小數點或逗號。
To support jQuery validation for non-English locales that use a comma (",") for a decimal point,
使用 jQuery validation 支持在非英文場景使用逗號與小數點,
and non US-English date formats, you must take steps to globalize your app.
以及非美式日期格式,你須要作一些操做來全球化你的應用。
See Additional resourcesfor more information.
查看 Additional resources 能夠得到更多信息。
For now, just enter whole numbers like 10.
目前,我先只輸入像10這樣的整數。
• In some locales you need to specify the date format. See the highlighted code below.
在某些場景,你須要專門指定特殊的日期格式。看下面高亮的代碼部分:

 1 using System;
 2 using System.ComponentModel.DataAnnotations;
 3 
 4 namespace MvcMovie.Models
 5 {
 6     public class Movie
 7     {
 8         public int ID { get; set; }
 9         public string Title { get; set; }
10         [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
11         public DateTime ReleaseDate { get; set; }
12         public string Genre { get; set; }
13         public decimal Price { get; set; }
14     }
15 }
C# code

We'll talk about DataAnnotations later in the tutorial.
咱們將在本教程的後面講解數據註解。
Tapping Create causes the form to be posted to the server, where the movie information is saved in a database.
點擊 Create 將會向服務器發送表單,而後電影數據的信息就會保存到數據庫。
The app redirects to the /Movies URL, where the newly created movie information is displayed.
應用重定向到 /Movies 地址,在這個頁面,新建立的電影信息就會顯示出來。

Create a couple more movie entries. Try the Edit, Details, and Delete links, which are all functional.
建立更多的電影條目,嘗試 Edit, Details, and Delete 連接操做,他們都是功能完整的。
Dependency Injection
依賴注入
Open the Startup.cs file and examine ConfigureServices:
打開 Startup.cs 文件,並查看 ConfigureServices 方法:

 

1 public void ConfigureServices(IServiceCollection services)
2 {
3     // Add framework services.
4     services.AddMvc();
5 
6     services.AddDbContext<MvcMovieContext>(options =>
7             options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
8 }
C# code

 

The highlighted code above shows the movie database context being added to the Dependency Injection container.
上面高亮的代碼顯示 movie DB上下文已經添加到了DI容器中。
The line following services.AddDbContext<MvcMovieContext>(options => is not shown (see your code).
services.AddDbContext<MvcMovieContext>(options => 這行代碼下的代碼沒有展現(查看代碼文件就能看到)。
It specifies the database to use and the connection string. => is a lambda operator.
它指定了數據庫使用的鏈接字符串。=> 符號是 lambda 操做符。
Open the Controllers/MoviesController.cs file and examine the constructor:
打開 Controllers/MoviesController.cs 文件並查看構造函數:

 

1 public class MoviesController : Controller
2 {
3     private readonly MvcMovieContext _context;
4 
5     public MoviesController(MvcMovieContext context)
6     {
7         _context = context;
8     }
C# code

 

The constructor uses Dependency Injection to inject the database context (MvcMovieContext) into the controller.
構造函數使用 DI 注入DB上下文到控制器中。
The database context is used in each of the CRUD methods in the controller.
DB上下文將會在控制器中的每一個CRUD方法中使用。
Strongly typed models and the @model keyword
強類型Model與@model 關鍵字
Earlier in this tutorial, you saw how a controller can pass data or objects to a view using the ViewDatadictionary.
在教程的前面部分,你已經明白如何用 ViewData 字典將數據從控制器傳遞給視圖使用。
The ViewData dictionary is a dynamic object that provides a convenient late-bound way to pass information to a view.
ViewData 字典是一個動態對象,它提供了一個後綁定方式以傳遞數據到視圖中。
MVC also provides the ability to pass strongly typed model objects to a view.
MVC同時也提供了向視圖傳遞強類型視圖的方式。
This strongly typed approach enables better compile-time checking of your code.
強類型在編譯代碼時能更好的檢查你的代碼。
The scaffolding mechanism used this approach (that is, passing a strongly typed model) with the MoviesController class and views when it created the methods and views.
基架的機制使用的相似這種,在建立控制器方法與視圖的時候。
Examine the generated Details method in the Controllers/MoviesController.cs file:
在 Controllers/MoviesController.cs 文件中查看自動生成的 Details 方法:

 

 1 // GET: Movies/Details/5
 2 public async Task<IActionResult> Details(int? id)
 3 {
 4     if (id == null)
 5     {
 6         return NotFound();
 7     }
 8 
 9     var movie = await _context.Movie
10         .SingleOrDefaultAsync(m => m.ID == id);
11     if (movie == null)
12     {
13         return NotFound();
14     }
15 
16     return View(movie);
17 }
C# code

 

The id parameter is generally passed as route data. For example http://localhost:5000/movies/details/1 sets:
id 參數一般是路由參數傳遞過來的。例如 http://localhost:5000/movies/details/1 中有多個路由段:
• The controller to the movies controller (the first URL segment).
第一段是 movies 控制器。
• The action to details (the second URL segment).
第二段是 details action方法。
• The id to 1 (the last URL segment).
第三段是 id=1 參數。
You can also pass in the id with a query string as follows:
固然你也能夠吧 id 參數放到查詢字符串裏面,以下URL:
http://localhost:1234/movies/details?id=1
The id parameter is defined as a nullable type (int?) in case an ID value is not provided.
id 參數被定義爲了可空類型,以適應ID未提供的狀況。
A lambda expression is passed in to SingleOrDefaultAsync to select movie entities that match the route data or query string value.
一個lambda 表達式 被作爲 SingleOrDefaultAsync 方法的參數以找出相應的數據實體(與路由參數或查詢字符串參數一致的的)。

1 var movie = await _context.Movie
2 .SingleOrDefaultAsync(m => m.ID == id);
C# code

If a movie is found, an instance of the Movie model is passed to the Details view:
若是數據實體被找到,則會如代碼所示的方式傳遞給視圖:

1 return View(movie);
C# code

Examine the contents of the Views/Movies/Details.cshtml file:
查看 Views/Movies/Details.cshtml 文件的內容,以下:

 

 1 @model MvcMovie.Models.Movie
 2 
 3 @{
 4     ViewData["Title"] = "Details";
 5 }
 6 
 7 <h2>Details</h2>
 8 
 9 <div>
10     <h4>Movie</h4>
11     <hr />
12     <dl class="dl-horizontal">
13         <dt>
14             @Html.DisplayNameFor(model => model.Title)
15         </dt>
16         <dd>
17             @Html.DisplayFor(model => model.Title)
18         </dd>
19         <dt>
20             @Html.DisplayNameFor(model => model.ReleaseDate)
21         </dt>
22         <dd>
23             @Html.DisplayFor(model => model.ReleaseDate)
24         </dd>
25         <dt>
26             @Html.DisplayNameFor(model => model.Genre)
27         </dt>
28         <dd>
29             @Html.DisplayFor(model => model.Genre)
30         </dd>
31         <dt>
32             @Html.DisplayNameFor(model => model.Price)
33         </dt>
34         <dd>
35             @Html.DisplayFor(model => model.Price)
36         </dd>
37     </dl>
38 </div>
39 <div>
40     <a asp-action="Edit" asp-route-id="@Model.ID">Edit</a> |
41     <a asp-action="Index">Back to List</a>
42 </div>
HTML code

 

By including a @model statement at the top of the view file, you can specify the type of object that the view expects.
經過在頂部包含一個@model 語句,你能夠指定視圖所要使用的模型類型。
When you created the movie controller, Visual Studio automatically included the following @model statement at the top of the Details.cshtml file:
在你添加movie控制器時,vs 自動在Details.cshtml 文件的頂部包含了@model 語句,以下所示:

1 @model MvcMovie.Models.Movie
C# code

This @model directive allows you to access the movie that the controller passed to the view by using a Model object that's strongly typed.
@model 指令容許你在視圖上以強類型的方式訪問控制器傳遞過來的Model 對象。
For example, in the Details.cshtml view, the code passes each movie field to the DisplayNameFor and DisplayFor HTML Helpers with the strongly typed Modelobject.
例如在Details.cshtml 視圖中,代碼用 DisplayNameFor 和DisplayFor 展示強類型Model 對象的每個字段。
The Create and Edit methods and views also pass a Movie model object.
Create 和Edit 一樣在視圖中解析Movie 模型對象。
Examine the Index.cshtml view and the Index method in the Movies controller.
查看Index.cshtml 視圖及控制器中的 Index 方法。
Notice how the code creates a List object when it calls the View method.
注意代碼中在調用View 方法時是如何建立一個List 集合對象的。
The code passes this Movies list from the Index action method to the view:
代碼中從Index 方法傳遞Movies 列表到視圖中,以下:

1 // GET: Movies
2 public async Task<IActionResult> Index()
3 {
4 return View(await _context.Movie.ToListAsync());
5 }
C# code

When you created the movies controller, scaffolding automatically included the following @modelstatement at the top of the Index.cshtml file:
當你建立movie控制器,基價自動會將以下代碼放到Index.cshtml 文件的頂部:

1 @model IEnumerable<MvcMovie.Models.Movie>
C# code

The @model directive allows you to access the list of movies that the controller passed to the view by using a Model object that's strongly typed.
@model 指令容許你以強類型的方式在視圖上訪問控制器傳遞過來的movies 列表。
For example, in the Index.cshtml view, the code loops through the movies with a foreach statement over the strongly typed Model object:
例如,在Index.cshtml 視圖中,經過foreach 語句循環movie列表中的每一個強類型Model 對象:

 

 1 @model IEnumerable<MvcMovie.Models.Movie>
 2 
 3 @{
 4     ViewData["Title"] = "Index";
 5 }
 6 
 7 <h2>Index</h2>
 8 
 9 <p>
10     <a asp-action="Create">Create New</a>
11 </p>
12 <table class="table">
13     <thead>
14         <tr>
15                 <th>
16                     @Html.DisplayNameFor(model => model.Title)
17                 </th>
18                 <th>
19                     @Html.DisplayNameFor(model => model.ReleaseDate)
20                 </th>
21                 <th>
22                     @Html.DisplayNameFor(model => model.Genre)
23                 </th>
24                 <th>
25                     @Html.DisplayNameFor(model => model.Price)
26                 </th>
27             <th></th>
28         </tr>
29     </thead>
30     <tbody>
31 @foreach (var item in Model) {
32         <tr>
33             <td>
34                 @Html.DisplayFor(modelItem => item.Title)
35             </td>
36             <td>
37                 @Html.DisplayFor(modelItem => item.ReleaseDate)
38             </td>
39             <td>
40                 @Html.DisplayFor(modelItem => item.Genre)
41             </td>
42             <td>
43                 @Html.DisplayFor(modelItem => item.Price)
44             </td>
45             <td>
46                 <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
47                 <a asp-action="Details" asp-route-id="@item.ID">Details</a> |
48                 <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
49             </td>
50         </tr>
51 }
52     </tbody>
53 </table>
HTML code

Because the Model object is strongly typed (as an IEnumerable<Movie> object), each item in the loop is typed as Movie.
由於Model 對象是強類型的,循環中的每一個對象都是Movie 類型。
Among other benefits, this means that you get compile-time checking of the code:
還有其它有點,好比你在編譯的同時也由編譯器自動檢查了代碼的正確性:

Additional resources
其它資源
• Tag Helpers
• Globalization and localization

 

 

                                         蒙

                                    2017-07-20 16:31 週四

                                    2017-07-21  15:10  修正

相關文章
相關標籤/搜索