.NET Core - MVC 添加模型

1. 添加数据模型类

  右键单击 Models 文件夹  => 添加 =>类 名称 "Movie.cs"=> 添加

  新增 Movie.cs 代码 :

    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; }
      }
    }

2. 添加NuGet包

  工具 => NuGet包管理器 => 程序包管理器控制台 => PM 运行命令:

    Install-Package Microsoft.EntityFrameworkCore.Design

    Install-Package Microsoft.EntityFrameworkCore.SqlServer

    上述命令添加:

    • EF Core SQL Server 提供程序。 提供程序包将 EF Core 包作为依赖项进行安装。

  生成项目以检查编译器错误。

3. 基架电影页面

  使用基架工具为电影模型生成Create、Read、Update和Delete(CRUD)页面

  右键Controllers文件夹 => 新建 => 新搭建基架的项目 => 通用 => MVC => 视图使用Entity Framework的MVC控制器 =>

    添加 => 模型类 : 选择“Movie (MvcMovie.Models)” [选择的是要生成的模型] =>

    数据上下文类 : 点击"+" 生成类名 MvcMovie.Data.MvcMovieContext 选择 "添加" => “视图”和“控制器名称”:保留默认值 => 添加。

    如果收到错误消息,请再次选择“添加”以重试。

    基架更新以下内容:

    • 在 MvcMovie.csproj 项目文件中插入所需的包引用。
    • 在 Program.cs 文件中注册数据库上下文。
    • 将数据库连接字符串添加到 appsettings.json 文件

  基架创建以下内容:

    • 电影控制器:Controllers/MoviesController.cs
    • “创建”、“删除”、“详细信息”、“编辑”和“索引”页面的 Razor 视图文件:Views/Movies/*.cshtml
    • 数据库上下文类:Data/MvcMovieContext.cs

  自动创建这些文件和文件更新被称为“基架”。

  此时不能使用基架页面,因为该数据库不存在。

  运行应用并选择“Movie App”链接会导致“无法打开数据库”或“无此类表: Movie”错误消息

4. 初始迁移

  使用 EF Core 迁移功能来创建数据库。

  迁移是可用于创建和更新数据库以匹配数据模型的一组工具。

  工具 => NuGet包管理器 => 程序包管理器控制台 => PM 运行命令:

    Add-Migration InitialCreate

    Update-Database

  • Add-Migration InitialCreate:生成 Migrations/{timestamp}_InitialCreate.cs 迁移文件。 InitialCreate 参数是迁移名称。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。 因为这是首次迁移,所以生成的类包含用于创建数据库架构的代码。 数据库架构基于在 MvcMovieContext 类中指定的模型。

  • Update-Database:将数据库更新到上一个命令创建的最新迁移。 此命令在用于创建数据库的 Migrations/{time-stamp}_InitialCreate.cs 文件中运行 Up 方法。

  Update-Database 命令将生成如下警告:

    No type was specified for the decimal column 'Price' on entity type 'Movie'.

    This will cause values to be silently truncated if they do not fit in the default precision and scale.

    Explicitly specify the SQL server column type that can accommodate all the values using 'HasColumnType()'.

  依文档所述 :忽略警告,它将在后面的学习中进行修复。

5. 测试应用

  运行应用并选择“Movie App”链接。

6. 检查生成的数据库上下文类和注册

  对于 EF Core,使用模型执行数据访问。

  模型由实体类和表示数据库会话的上下文对象构成。

  上下文对象允许查询并保存数据。

  数据库上下文派生自Microsoft.EntityFrameworkCore.DbContext 并指定要包含在数据模型中的实体。

  基架创建 Data/MvcMovieContext.cs 数据库上下文类,类中的代码 :

    DbSet<MvcMovie.Models.Movie> :表示数据库中的电影。

7. 依赖性注入

  ASP.NET Core 通过依赖关系注入(DI)生成。

  服务(如数据库上下文)在 Program.cs 中向 DI 注册。

  这些服务通过构造函数参数提供给需要它们的组件。

  在 Controllers/MoviesController.cs 文件中,构造函数使用依赖关系注入将 MvcMovieContext 数据库上下文注入到控制器中。

  数据库上下文将在控制器中的每个 CRUD方法中使用。

8.检查生成的数据库连接字符串

  基架向 appsettings.json 文件添加了一个连接字符串:    

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-7dc5b790-765f-4381-988c-5167405bb107;Trusted_Connection=True;MultipleActiveResultSets=true"
      }
    }

  进行本地开发时,NET .Core配置系统在 appsettings.json 文件中读取 ConnectionString 键。

9. InitialCreate类

  检查 Migrations/20220627031522_InitialCreate.cs 迁移文件:

    前面数字字符串是迁移时间串

    检查文件代码,其中 : 

    • 方法Up 创建 Movie 表,并将 Id 配置为主键。
    • 方法Down 还原 Up 迁移所做的架构更改。      

10. 控制器中的依赖项注入

  打开 Controllers/MoviesController.cs 文件并检查构造函数:

    构造函数使用依赖关系注入将数据库上下文 (MvcMovieContext) 注入到控制器中。

    数据库上下文将在控制器中的每个CRUD方法中使用。

    测试“创建”页。 输入并提交数据。

    测试“编辑”、“详细信息”和“删除”页 。

11. 强类型模型和@model指令

  MVC 提供将强类型模型对象传递给视图的功能。

  此强类型方法启用编译时代码检查。

  基架机制在 MoviesController 类和视图中传递了一个强类型模型。

  检查 Controllers/MoviesController.cs 文件中生成的 Details 方法:

    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 语句可指定视图期望的对象类型:

      @model MvcMovie.Models.Movie

    此 @model 指令允许访问控制器传递给视图的影片。 

    Model 对象为强类型对象。例如,在 Details.cshtml 视图中,代码通过强类型的 Model 对象将每个电影字段传递给 DisplayNameFor 和 DisplayFor HTML 帮助程序。 

      例:

        <dt class = "col-sm-2">
          @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class = "col-sm-10">
          @Html.DisplayFor(model => model.Title)
        </dd>

    Create 和 Edit 方法以及视图也传递一个 Movie 模型对象。

  检查电影控制器中的 Index.cshtml 视图和 Index 方法。

  代码将此 Movies 列表从 Index 操作方法传递给视图:

    public async Task<IActionResult> Index()

    {
      return _context.Movie != null ?
            View(await _context.Movie.ToListAsync()) :
            Problem("Entity set 'MvcMovieContext.Movie' is null.");
    }

  创建电影控制器后,基架将以下 @model 语句包含在 Index.cshtml 文件的顶部:

    @model IEnumerable<MvcMovie.Models.Movie>

    @model 指令允许使用强类型的 Model 对象访问控制器传递给视图的电影列表。

    例如,在 Index.cshtml 视图中,代码使用 foreach 语句通过强类型 Model 对象对电影进行循环遍历:

      @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>
        }

    因为 Model 对象为强类型(作为 IEnumerable<Movie> 对象),因此循环中的每个项都被类型化为 Movie。 

posted @ 2022-06-27 14:09  大师兄被妖怪抓走了  阅读(300)  评论(0编辑  收藏  举报