原文:Adding a model

作者:Rick Anderson

翻译:娄宇(Lyrics)

校对:许登洋(Seay)孟帅洋(书缘)姚阿勇(Mr.Yao)夏申斌

在这一节里,你将添加一些类来管理数据库中的电影数据。这些类将成为 MVC 应用程序中的 “Model” 部分。

你将使用 .NET Framework 中名为 Entity Framework Core 的数据库访问技术来定义和使用这些数据模型类。Entity Framework Core (通常被称为 EF Core) 有一种具有特色的被称为 Code First 的开发模式。你先编写代码,然后通过这些代码创建数据库表。 Code First 允许你通过编写一些简单的类(也被称为 POCO 类, "plain-old CLR objects." )来创建数据模型对象,然后根据你的类创建数据库。如果你需要先创建数据库,你仍然可以按照本教程来学习 MVC 和 EF 应用程序开发。

使用个人用户账户身份认证创建新项目

在 Visual Studio 当前版本的 ASP.NET Core MVC 工具中,仅在以个人用户账户身份认证方式创建新项目时支持通过基架生成模型。我们希望在下一个工具更新中修复这个问题。直到问题被修复之前,你需要以相同的名称创建新项目。因为项目有相同的名字,你需要在其他的文件夹中创建。

在 Visual studio 起始页(Start Page),点击 新建项目(New Project)

或者,你可以使用菜单来创建新项目。点击 文件(File)> 新建(New) > 项目(Project)

完成 新建项目(New Project) 对话框:

  • 在左窗格,点击 Web
  • 在中间窗格,点击 ASP.NET Core Web Application (.NET Core)
  • 将位置更改为你创建的前一个项目的不同目录,否则你将遇到错误
  • 命名项目为“MvcMovie”(将项目命名为“MvcMovie”非常重要,当你复制代码时,命名空间将会匹配)
  • 点击 确定(OK)

警告

在本教程中,你必须将 身份验证(Authentication) 设置为 个人用户账户(Individual User Accounts) ,以便基架引擎能正常工作(译者注:不同的身份认证通过基架引擎生成的代码不一样,为了教程顺利进行,此处必须选用个人用户账户的认证方式)。

New ASP.NET Core Web Application - MvcMovie 对话框中:

  • 点击 Web 应用程序(Web Application)
  • 点击 更改身份验证(Change Authentication) 按钮并将身份验证改为 Individual User Accounts(个人用户账户) 之后点击 确定(OK)

按照 change-title-link-reference-label 的指示你可以点击 MvcMovie 链接来调用 Movie 控制器(Controller)。我们将在本教程中通过基架生成 Movie 控制器(Controller)。

添加数据模型类

在解决方案资源管理器中,右键点击 Models 文件夹 > 添加 > 。将类名命名为 Movie 并且添加以下属性:

using System;

namespace MvcMovie.Models
{
public class Movie
{
public int ID { get; set; } //手动高亮
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
}

除了你用来构造电影的属性,还需要一个 ID 字段来作为数据库主键。生成项目。如果你没有生成这个应用程序,你将在下一节中遇到错误。我们终于为这个 MVC 应用程序添加了一个 Model 。

通过基架生成一个控制器(Controller)

解决方案资源管理器 中,右键点击 Controllers 文件夹 > 添加 > 控制器

添加基架 对话框中,点击 MVC Controller with views, using Entity Framework > 添加

完成 添加控制器(Add Controller) 对话框

  • 模型类(Model class): Movie(MvcMovie.Models)
  • 数据上下文类(Data context class): ApplicationDbContext(MvcMovie.Models)
  • 视图(Views): 保持默认的选项
  • 控制器名称(Controller name): 保持默认的 MoviesController
  • 点击 添加(Add)

Visual Studio 基架引擎创建的东西如下:

  • 一个电影控制器(Controller)(Controllers/MoviesController.cs
  • Create、Delete、Details、Edit 以及 Index 的 Razor 视图文件(Views/Movies)

Visual Studio 为你自动创建 CRUD(创建、读取、更新以及删除)Action 方法和视图(View)(自动创建 CRUD Action 方法和 View 视图被称为 搭建基架(scaffolding))。很快你将拥有一个可以让你创建、查看、编辑以及删除电影条目的完整功能的 Web 应用程序。

运行这个应用程序并且点击 Mvc Movie 链接。你将遇到以下错误:

我们将按照这些指示来为 Movie 应用程序准备好数据库。

更新数据库

警告

你必须在更新数据库之前停止 IIS Express。

停止 IIS Express:

  • 右键点击通知区域的 IIS Express 系统托盘图标

  • 点击 退出(Exit) 或者 停止站点(Stop Site)

  • 除此之外, 你可以退出并重启 Visual Studio

  • 在项目文件夹(MvcMovie/src/MvcMovie)打开命令提示符。按照以下说明,以一个快捷的方式打开项目文件夹

    • 打开一个在项目根目录下的文件(在这个例子中,使用 Startup.cs )。
    • 右键点击 Startup.cs > 打开所在的文件夹(Open Containing Folder)

    • Shift + 右键点击一个文件夹 > 在此处打开命令窗口(Open command window here)

    • 运行 cd .. 将路径退回项目文件夹
  • 在命令提示符中运行以下命令:

  dotnet ef migrations add Initial
dotnet ef database update

注意

如果 IIS-Express 在运行中,你会遇到错误 CS2012: Cannot open 'MvcMovie/bin/Debug/netcoreapp1.0/MvcMovie.dll' for writing -- 'The process cannot access the file 'MvcMovie/bin/Debug/netcoreapp1.0/MvcMovie.dll' because it is being used by another process.'

dotnet ef 命令

  • dotnet (.NET Core) 是 .NET 的跨平台实现。你可以在这里了解它。
  • dotnet ef migrations add Initial 运行 Entity Framework .NET Core CLI 迁移命令并创建初始化迁移。参数 "Initial" 可以是任意值,但是通常用这个作为第一个(初始的) 数据库迁移。这个操作创建了一个 Data/Migrations/_Initial.cs 文件,这个文件包含了添加(或删除)Movie 表到数据库的迁移命令。
  • dotnet ef database update dotnet ef database update 用我们刚刚创建的迁移来更新数据库。

测试一下

注意

如果你的浏览器不能连接到 Movie 应用程序,你可能需要等待 IIS Express 加载它。它有时需要 30 秒来构建应用程序并准备好响应请求。

  • 运行应用程序并点击 Mvc Movie 链接
  • 点击 Create New 链接并创建电影

注意

你也许不能在 Price 字段中输入小数点或逗号。为了实现对非英语环境中用逗号(",")来表示小数点,以及非美国英语日期格式的 jQuery 验证,你必须采取措施国际化你的应用程序。查看额外的资源获取更多的信息。现在仅仅输入完整的数字,比如10。


注意

在某些地区你需要指定日期格式。查看下方高亮代码。

点击 Create 提交表单到服务器,将电影数据保存到数据库中。然后重定向到 /Movies URL ,你可以在列表中看到新创建的电影。

using System;
using System.ComponentModel.DataAnnotations; //手动高亮 namespace MvcMovie.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] //手动高亮
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
}

再创建几个电影条目。尝试 EditDetailsDelete 链接来执行各个功能。

检查生成的代码

打开 Controllers/MoviesController.cs 文件并检查生成的 Index 方法。 MoviesController 中包含 Index 方法的部分如下所示:

public class MoviesController : Controller
{
private readonly ApplicationDbContext _context; public MoviesController(ApplicationDbContext context)
{
_context = context;
} // GET: Movies
public async Task<IActionResult> Index()
{
return View(await _context.Movie.ToListAsync());
}

构造函数使用依赖注入将数据库上下文注入到控制器(Controller)。 数据上下文在控制器(Controller)中被用来执行增删改查(CRUD)方法。

一个到 MoviesController 的请求从 Movies 表返回所有的条目,然后传递数据到 Index 视图 (View) 。

强类型模型与 @model 关键字

在之前的教程中,你看到了控制器(Controller)如何通过 ViewData 字典传递数据到一个视图(View)。 ViewData 字典是一个动态类型对象,它提供了一种便捷的后期绑定方式将信息传递给视图。

MVC 也提供了传递强类型数据给视图的能力。这种强类型的方式可以提供给你更好的代码编译时检查,并在 Visual Studio(VS) 中具有更丰富的智能感知。VS 中的基架机制在为 MoviesController 类创建方法(Action)和视图(View)的时候就采用了这种方式(即,传递强类型模型)。

检查在 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.SingleOrDefaultAsync(m => m.ID == id);
if (movie == null)
{
return NotFound();
} return View(movie);
}

id 参数一般作为路由数据传递,例如 http://localhost:1234/movies/details/1 将:

  • Controller 设置为 movies(对应第一个 URL 段)
  • Action 设置为 details(对应第二个 URL 段)
  • id 设置为 1(对应最后一个 URL 段)

你也可以向下面一样通过查询字符串(Query String)传递 id

http://localhost:1234/movies/details?id=1

如果电影被找到了, Movie 模型(Model)的实例将被传递给 Details 视图(View)。

  return View(movie);

检查 Views/Movies/Details.cshtml 文件的内容:

@model MvcMovie.Models.Movie  <!--手动高亮-->

@{
ViewData["Title"] = "Details";
} <h2>Details</h2> <div>
<h4>Movie</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Genre)
</dt>
<dd>
@Html.DisplayFor(model => model.Genre)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Price)
</dt>
<dd>
@Html.DisplayFor(model => model.Price)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ReleaseDate)
</dt>
<dd>
@Html.DisplayFor(model => model.ReleaseDate)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Title)
</dt>
<dd>
@Html.DisplayFor(model => model.Title)
</dd>
</dl>
</div>
<div>
<a asp-action="Edit" asp-route-id="@Model.ID">Edit</a> |
<a asp-action="Index">Back to List</a>
</div>

通过在视图(View Template)文件顶部加入一个 @model 语句,你可以指定视图(View)所期望的对象类型。当你创建这个 MoviesController 时, Visual Studio 自动在 Details.cshtml 顶部加入了 @model 语句后面的部分。

  @model MvcMovie.Models.Movie

@model 指令允许你访问从控制器(Controller)传递给视图(View)的这个强类型电影 Model 对象。例如,在 Details.cshtml 视图中,代码用强类型 Model 对象传递所有的电影字段到 DisplayNameForDisplayFor HTML 帮助类(HTML Helper)里。 CreateEdit 方法和视图(View)也传递一个 Movie 模型(Model)对象。

检查 Index.cshtml 视图(View)和 MoviesController 里的 Index 方法。注意观察代码在调用 View 方法时,是如何创建一个 列表(List) 对象的。这段代码将 Movies 列表从 Index Action 方法传递给视图(View):

public async Task<IActionResult> Index()
{
return View(await _context.Movie.ToListAsync());
}

当你创建这个 MoviesController 时,Visual Studio 自动在 Index.cshtml 顶部加入以下 @model 语句:

@model IEnumerable<MvcMovie.Models.Movie>

@model 指令允许你访问电影列表这个从控制器(Controller)传递给视图(View)的强类型 Model 对象。例如,在 Index.cshtml 视图中,代码通过 foreach 语句遍历了电影列表这个强类型的 模型(Model) 对象。

@model IEnumerable<MvcMovie.Models.Movie>   <!--手动高亮-->

@{
ViewData["Title"] = "Index";
} <h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p> <table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) { <!--手动高亮-->
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre) <!--手动高亮-->
</td>
<td>
@Html.DisplayFor(modelItem => item.Price) <!--手动高亮-->
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate) <!--手动高亮-->
</td>
<td>
@Html.DisplayFor(modelItem => item.Title) <!--手动高亮-->
</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> 对象),循环中的每一个 item 的类型被类型化为 Movie 。除了其他好处外,这意味着你将获得代码的编译时检查以及在代码编辑器里得到完整的智能感知支持:

现在你有了数据库和用于显示、编辑、更新以及删除数据的页面。在下一篇教程中,我们将学习使用数据库。

额外的资源

修订历史

  1. 2016/07/08,MS1;
  2. 2016/07/09,修订至 1.0.0

返回目录

ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model的更多相关文章

  1. ASP.NET Core 中文文档 第二章 指南(4.6)Controller 方法与视图

    原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...

  2. ASP.NET Core 中文文档 第二章 指南 (09) 使用 Swagger 生成 ASP.NET Web API 在线帮助测试文档

    原文:ASP.NET Web API Help Pages using Swagger 作者:Shayne Boyer 翻译:谢炀(kiler) 翻译:许登洋(Seay) 对于开发人员来说,构建一个消 ...

  3. ASP.NET Core 中文文档 第二章 指南(1)用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序

    原文:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 作者:Daniel Roth.Steve Smith ...

  4. ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

    原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio 作者:Mike Wasson 和 Rick Anderso ...

  5. ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序

    原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...

  6. ASP.NET Core 中文文档 第二章 指南(4.1)ASP.NET Core MVC 与 Visual Studio 入门

    原文:Getting started with ASP.NET Core MVC and Visual Studio 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:刘怡(Alex ...

  7. ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB

    原文:Working with SQL Server LocalDB 作者:Rick Anderson 翻译: 魏美娟(初见) 校对: 孟帅洋(书缘).张硕(Apple).许登洋(Seay) Appl ...

  8. ASP.NET Core 中文文档 第二章 指南(5) 在 Nano Server 上运行ASP.NET Core

    原文 ASP.NET Core on Nano Server 作者 Sourabh Shirhatti 翻译 娄宇(Lyrics) 校对 刘怡(AlexLEWIS).许登洋(Seay).谢炀(kile ...

  9. ASP.NET Core 中文文档 第二章 指南(8) 使用 dotnet watch 开发 ASP.NET Core 应用程序

    原文:Developing ASP.NET Core applications using dotnet watch 作者:Victor Hurdugaci 翻译:谢炀(Kiler) 校对:刘怡(Al ...

随机推荐

  1. Ngrok让你的本地Web应用暴露在公网上

    1.Ngrok介绍 Ngrok是一个反向代理,通过在公共的端点和本地运行的Web服务器之间建立一个安全的通道.Ngrok可捕获和分析所有通道上的流量,便于后期分析和重放.简单来说,利用 Ngrok可以 ...

  2. ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

    ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...

  3. iOS开发之再探多线程编程:Grand Central Dispatch详解

    Swift3.0相关代码已在github上更新.之前关于iOS开发多线程的内容发布过一篇博客,其中介绍了NSThread.操作队列以及GCD,介绍的不够深入.今天就以GCD为主题来全面的总结一下GCD ...

  4. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  5. 易用BPM时代,企业如何轻松驾驭H3?

    众所周知,BPM作为企业发展的推动力,能敏捷高效的融合业务流程和信息资源.通过综合考虑流程的成本.效率.质量等方面因素,用IT系统将调整后的流程固化下来,从而降低企业管理成本,提高内部运营效率,提升企 ...

  6. Android之三种网络请求解析数据(最佳案例)

    AsyncTask解析数据 AsyncTask主要用来更新UI线程,比较耗时的操作可以在AsyncTask中使用. AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法. ...

  7. iOS开源项目周报1229

    由OpenDigg 出品的iOS开源项目周报第三期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. Ma ...

  8. docker4dotnet #4 使用Azure云存储构建高速 Docker registry

    使用Docker来构建应用程序最常见的操作就是 docker run 或者 docker pull了,但是由于众所周知的原因,在国内想要高速稳定的获取docker hub上面的资源并不是件容易的事情, ...

  9. Oracle 表空间和用户权限管理

    一. 表空间 Oracle数据库包含逻辑结构和物理结构. 数据库的物理结构指的是构成数据库的一组操作系统文件. 数据库的逻辑结构是指描述数据组织方式的一组逻辑概念以及它们之间的关系. 表空间是数据库逻 ...

  10. Linux硬件IO的优化简介

    Linux硬件IO的优化简介 首先简单介绍下有哪些硬件设备如下(由于硬件种类厂家等各种因素我就不在此多做介绍有兴趣的可以自行学习): 1.CPU:中央处理器,是计算机运算控制的核心部件之一,相当于人的 ...