本系列的学习都是来自微软的官方文档EF Core数据访问。具体内容和代码可以访问官方文档查看。
入门中可以学到
- 创建ASP.NET Core MVC Web应用
- 设置网站样式
- 了解EF Core NuGet包
- 创建数据模型
- 创建数据库上下文
- 为依赖注入注册上下文
- 使用测试数据初始化数据库
- 创建控制器和视图
- 查看数据库
创建web应用
这里大家可以自己查看文档,就不写了。
设置网站样式
通过设置_layout.cshtml来更改站点菜单、布局和主页信息。
通过官方文档_layout.cshtml可以更加清楚什么是布局和样式。
布局
大多数web应用都有一个通用布局,可以在页面切换时为用户提供一致体验。该布局通常包括应用标头、导航或菜单元素以及页脚等常见的用户界面元素。
按照约定,ASP.NET Core应用的默认布局名为_layout.cshtml。在本例中_layout.cshtml的布局文件的位置如下:
在本例中布局文件主要定义了几个页面信息
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
crossorigin="anonymous"
integrity="sha256-eSi1q2PG6J7g7ib17yAaWMcrr5GrtohYChqibrV7PBE=" />
</environment>
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Students" asp-action="Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Courses" asp-action="Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Instructors" asp-action="Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Departments" asp-action="Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<partial name="_CookieConsentPartial" />
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2019 - Contoso University - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
</environment>
<environment exclude="Development">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.bundle.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha256-E/V4cWE4qvAeO5MOhjtGtqDzPndRO1LBk8lJ/PR7CA4=">
</script>
</environment>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
如果其他页面都要使用这个布局文件的话,需要进行指定。
指定文件为_ViewStart.cshtml
@{
Layout = "_Layout";
}
更新home控制器的Index页面信息
不写了
创建数据模型
学生类Student可以注册多个课程,所以Student与Enrollment是一对多的关系,课程Course也可以被多次注册,所以类Course与Enrollment也是一对多的关系。
一对多或者存在外键属性,在类中通过将另外的类作为属性来实现。
using System;
using System.Collections.Generic;
namespace ContosoUniversity.Models
{
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
ID属性将成为数据库表的主键。默认情况下,EF会将名为ID或classnameID(类名+ID)解析成主键。
Enrollments属性是导航属性,即包含此实体相关的其他实体。
Enrollment实体
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
EnrollmentID属性被设为主键。
Grade使用了枚举,声明类型后的?表示grade属性可以为Null,这在生成到数据表的关系中也能看到。
studentID是外键属性,student是与其对应的导航属性,用于可以查出对应的学生信息。Enrollment只包含一个学生信息,所以只有一个student属性,而不是使用ICollenction。
CourseID也是一样的外键属性。
如果一个属性名为<navigation property name><primary key property name>
EF就会将这个属性解析为外键属性。(如本例中Student实体的外键是ID,也可以是studentID,Student是Enrollment的导航属性,所以Enrollment实体中studentID就会被解析成外键)。
CREATE TABLE [dbo].[Enrollments] (
[EnrollmentID] INT IDENTITY (1, 1) NOT NULL,
[CourseID] INT NOT NULL,
[StudentID] INT NOT NULL,
[Grade] INT NULL,
CONSTRAINT [PK_Enrollments] PRIMARY KEY CLUSTERED ([EnrollmentID] ASC),
CONSTRAINT [FK_Enrollments_Courses_CourseID] FOREIGN KEY ([CourseID]) REFERENCES [dbo].[Courses] ([CourseID]) ON DELETE CASCADE,
CONSTRAINT [FK_Enrollments_People_StudentID] FOREIGN KEY ([StudentID]) REFERENCES [dbo].[People] ([ID]) ON DELETE CASCADE
);
类似的创建Course实体
创建数据库上下文
数据库上下文是实现EF功能的核心,将给定的数据模型与EF功能相协调的主要类就是数据库上下文,可以通过继承Microsoft.EntityFrameworkCore.DbContext
类的方式创建此类。
如
using ContosoUniversity.Models;
using Microsoft.EntityFrameworkCore;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
{
}
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Student> Students { get; set; }
}
}
当数据库创建完成之后,EF会创建一系列数据表,表名默认和DbSet属性名相同。
注册数据库上下文
ASP.NET Core默认实现依赖注入。在应用程序启动过程中通过依赖注入注册相关服务。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
}
然后按照例子创建对应的种子数据,打开PM控制台
输入add-migration InitialCreate
update-database
可以看到在数据库中已经创建好了对应的数据库表了。