3.将模型添加到 ASP.NET Core MVC 应用
添加数据模型类
右键单击 Models 文件夹,然后单击“添加” > “类”。 将类命名“Movie”。
向 Movie 类添加以下属性:
using System;
using System.ComponentModel.DataAnnotations;
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; }
}
}
Movie 类包含:
数据库需要 Id 字段以获取主键。
[DataType(DataType.Date)]:DataType 属性指定数据的类型 (Date)。 通过此特性:
用户无需在数据字段中输入时间信息。
仅显示日期,而非时间信息。
搭建“电影”模型的基架
基架工具将生成页面,用于对“电影”模型执行创建、读取、更新和删除 (CRUD) 操作。
在解决方案资源管理器中,右键单击“Controllers”文件夹 >“添加”>“新搭建基架的项目”。
在“添加基架”对话框中,选择“包含视图的 MVC 控制器(使用 Entity Framework)”>“添加”。
填写“添加控制器”对话框:
模型类: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。
除其他优点之外,这意味着可对代码进行编译时检查:
3.将模型添加到 ASP.NET Core MVC 应用的更多相关文章
- 2.将视图添加到 ASP.NET Core MVC 应用
在本部分中,将修改 HelloWorldController 类,进而使用 Razor 视图文件来顺利封装为客户端生成 HTML 响应的过程. 当前,Index 方法返回带有在控制器类中硬编码的消息的 ...
- 1.将控制器添加到 ASP.NET Core MVC 应用
模型-视图-控制器 (MVC) 体系结构模式将应用分成 3 个主要组件:模型 (M).视图 (V) 和控制器 (C). 模型(M):表示应用数据的类. 模型类使用验证逻辑来对该数据强制实施业务规则. ...
- ASP.NET Core MVC 2.1 顶级参数验证
本文讨论ASP.NET Core 2.1中与ASP.NET Core MVC / Web API控制器中的模型绑定相关的功能.虽说这是一个功能,但从我的角度来看,它更像是一个错误修复! 请注意,我使用 ...
- 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】
Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...
- ASP.NET Core MVC/WebAPi 模型绑定探索
前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...
- 创建ASP.NET Core MVC应用程序(6)-添加验证
创建ASP.NET Core MVC应用程序(6)-添加验证 DRY原则 DRY("Don't Repeat Yourself")是MVC的设计原则之一.ASP.NET MVC鼓励 ...
- 创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段
创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段 添加查询功能 本文将实现通过Name查询用户信息. 首先更新GetAll方法以启用查询: public async ...
- 创建ASP.NET Core MVC应用程序(4)-添加CRUD动作方法和视图
创建ASP.NET Core MVC应用程序(4)-添加CRUD动作方法和视图 创建CRUD动作方法及视图 参照VS自带的基架(Scaffold)系统-MVC Controller with view ...
- 创建ASP.NET Core MVC应用程序(1)-添加Controller和View
创建ASP.NET Core MVC应用程序(1)-添加Controller和View 参考文档:Getting started with ASP.NET Core MVC and Visual St ...
随机推荐
- centos8.0安装docker
背景简介: 前两天红帽正式发布了RHEL8,网上同时也有了CentOS8,一直在接触容器方面,为了尝鲜,下载了CentOS8,并尝试安装docker,不料竟然还报了个错(缺少依赖),故及时记录一下,方 ...
- shell expect的简单实用
一.在shell脚本中嵌入expect来实现密码输入 expect是一个自动交互功能的工具.expect是开了一个子进程,通过spawn来执行shell脚本,监测到脚本的返回结果,通过expect判断 ...
- 第08组 Beta冲刺(4/4)
队名 八组评分了吗 组长博客链接(5分) ( https://www.cnblogs.com/leemelon/p/12040924.html ) 作业博客 [作业链接] (https://edu.c ...
- 第08组 Beta冲刺(1/4)
队名 八组评分了吗 组长博客链接(2分) 小李的博客 作业链接 组员1李昕晖(组长) 过去两天完成了哪些任务 文字/口头描述 12月3号了解各个小组的进度与难以攻破的地方,晚上安排开会,安排新的冲刺任 ...
- Spring Cloud Ribbon 源码分析---负载均衡算法
上一篇分析了Ribbon如何发送出去一个自带负载均衡效果的HTTP请求,本节就重点分析各个算法都是如何实现. 负载均衡整体是从IRule进去的: public interface IRule{ /* ...
- Spark2.x(六十三):(Spark2.4)Driver如何把Task(闭包等)分配给Executor
在Spark中一个appliation可能包含多个job,每个job都是由SparkContext#runJob(...)触发的,一个Job下包含1个或多个Stage,Job的最后一个stage为Re ...
- XML-Signature 语法和签名
一段 XML-signature 的 demo: <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> &l ...
- JAVA中String空对象的字符串拼接
今天使用JSONObject中get一个不存在的对线,最后拼接成sql语句插入数据库时,最后数据库中的值为字符串'null',而不是空对象. 追踪许久才发现自己的java白学了. java strin ...
- mysql数据库架构设计与优化
mysql数据库架构设计与优化 2019-04-23 20:51:20 无畏D尘埃 阅读数 179 收藏 更多 分类专栏: MySQL 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...
- phpspreadsheet 中文文档(五)节约内存+PHPExcel迁移
2019年10月11日14:03:31 节省内存 PhpSpreadsheet在工作表中平均每个单元格使用约1k,因此大型工作簿可以迅速用尽可用内存.单元缓存提供了一种机制,使PhpSpreadshe ...