网站空间是啥,互联网博客网站,24小时24元网站建设,防红短链接生成接口地址系统必备 .NET Core 2.0.0 SDK 或更高版本。已安装 ASP.NET 和 Web 开发工作负载的 Visual Studio 2017 15.3 版或更高版本。创建Web应用程序 打开 Visual Studio 并创建一个新 ASP.NET Core C# web 项目名为”ContosoUniversity”。 从文件菜单上#xff0c;选择新建 项…系统必备 .NET Core 2.0.0 SDK 或更高版本。已安装 ASP.NET 和 Web 开发工作负载的 Visual Studio 2017 15.3 版或更高版本。创建Web应用程序 打开 Visual Studio 并创建一个新 ASP.NET Core C# web 项目名为”ContosoUniversity”。 从文件菜单上选择新建 项目。 从左窗格中选择已安装 Visual C# Web。 选择“ASP.NET Core Web 应用程序”项目模板。 输入ContosoUniversity作为名称然后单击确定。 在 “新建 ASP.NET Core Web 应用程序” 对话框选择ASP.NET Core 2.1和 Web 应用程序 模型-视图-控制器模板。 注意本教程需要安装 ASP.NET Core 2.0 和 EF Core 2.0 或更高版本。 请确保身份验证设置为不进行身份验单击“确定”。 修改页面菜单布局和主页 打开Views/Shared/_Layout.cshtml并进行以下更改 将文件中的”ContosoUniversity”更改为”Contoso University”。 需要更改三个地方。 添加菜单项StudentsCoursesInstructors和Department并删除Contact菜单项。 1 lia asp-area asp-controllerStudents asp-actionIndexStudents/a/li
2 lia asp-area asp-controllerCourses asp-actionIndexCourses/a/li
3 lia asp-area asp-controllerInstructors asp-actionIndexInstructors/a/li
4 lia asp-area asp-controllerDepartments asp-actionIndexDepartments/a/li 在Views/Home/Index.cshtml将文件的内容替换为以下代码以将有关 ASP.NET 和 MVC 的内容替换为有关此应用程序的内容 {ViewData[Title] Home Page;
}div classjumbotronh1Contoso University/h1
/div
div classrowdiv classcol-md-4h2Welcome to Contoso University/h2pContoso University is a sample application thatdemonstrates how to use Entity Framework Core in anASP.NET Core MVC web application./p/divdiv classcol-md-4h2Build it from scratch/h2pYou can build the application by following the steps in a series of tutorials./ppa classbtn btn-default hrefhttps://docs.asp.net/en/latest/data/ef-mvc/intro.htmlSee the tutorial raquo;/a/p/divdiv classcol-md-4h2Download it/h2pYou can download the completed project from GitHub./ppa classbtn btn-default hrefhttps://github.com/aspnet/Docs/tree/master/aspnetcore/data/ef-mvc/intro/samples/cu-finalSee project source code raquo;/a/p/div
/div View Code 按 CTRL F5 来运行该项目或从菜单选择调试 开始执行不调试。 你会看到首页和将通过这个教程创建的页对应的选项卡。 数据访问部分使用 EF Core 若要为项目添加 EF Core 支持需要安装相应的数据库驱动包。 本教程使用 SQL Server相关驱动包Microsoft.EntityFrameworkCore.SqlServer。 该包包含在Microsoft.AspNetCore.All 包中因此不需要手动安装。此包和其依赖项 (Microsoft.EntityFrameworkCore和Microsoft.EntityFrameworkCore.Relational) 一起提供 EF 的运行时支持。 创建数据模型 创建 Contoso 大学应用程序的实体类从以下三个实体类开始。 Student和Enrollment实体之间是一对多的关系Course和Enrollment实体之间也是一个对多的关系。 换而言之一名学生可以修读任意数量的课程, 并且某一课程可以被任意数量的学生修读。 在Models文件夹中创建一个名为Student.cs的类文件并且将模板代码替换为以下代码。 1 using System;2 using System.Collections.Generic;3 4 namespace ContosoUniversity.Models5 {6 public class Student7 {8 public int ID { get; set; }9 public string LastName { get; set; }
10 public string FirstMidName { get; set; }
11 public DateTime EnrollmentDate { get; set; }
12
13 public ICollectionEnrollment Enrollments { get; set; }
14 }
15 } ID属性将成为对应于此类的数据库表中的主键。 默认情况下EF 将会将名为ID或classnameID的属性解析为主键。 Enrollments属性是导航属性。 导航属性中包含与此实体相关的其他实体。 在这个案例下Student entity中的Enrollments属性会保留所有与Student实体相关的Enrollment。 换而言之如果在数据库中有两行描述同一个学生的修读情况 两行的 StudentID 值相同而且 StudentID 作为外键和某位学生的主键值相同Student实体的Enrollments导航属性将包含那两个Enrollment实体。 如果导航属性可以具有多个实体 如多对多或一对多关系那么导航属性的类型必须是可以添加、 删除和更新条目的容器如ICollectionT。 你可以指定ICollectionT或实现该接口类型如ListT或HashSetT。 如果指定ICollectionTEF在默认情况下创建HashSetT集合。 在Models文件夹中创建Enrollment.cs并且用以下代码替换现有代码 1 namespace ContosoUniversity.Models2 {3 public enum Grade4 {5 A, B, C, D, F6 }7 8 public class Enrollment9 {
10 public int EnrollmentID { get; set; }
11 public int CourseID { get; set; }
12 public int StudentID { get; set; }
13 public Grade? Grade { get; set; }
14
15 public Course Course { get; set; }
16 public Student Student { get; set; }
17 }
18 } EnrollmentID属性将被设为主键; 此实体使用classnameID模式而不是如Student实体那样直接使用ID。 通常情况下你选择一个主键模式并在你的数据模型自始至终使用这种模式。 在这里使用了两种不同的模式只是为了说明你可以使用任一模式来指定主键。 Grade属性是enum。 Grade声明类型后的?表示Grade属性可以为 null。 评级为 null 和评级为零是有区别的 –null 意味着评级未知或者尚未分配。 StudentID属性是一个外键Student是与其且对应的导航属性。 Enrollment实体与一个Student实体相关联因此该属性只包含单个Student实体 (与前面所看到的Student.Enrollments导航属性不同后Student中可以容纳多个Enrollment实体)。 CourseID属性是一个外键Course是与其对应的导航属性。 Enrollment实体与一个Course实体相关联。 如果一个属性名为导航属性名主键属性名Entity Framework 就会将这个属性解析为外键属性(例如Student实体的主键是IDStudent是Enrollment的导航属性所以Enrollment实体中StudentID会被解析为外键)。 此外还可以将需要解析为外键的属性命名为主键属性名(例如CourseID由于Course实体的主键所以CourseID也被解析为外键)。 在Models文件夹中创建Course.cs并且用以下代码替换现有代码 1 using System.Collections.Generic;2 using System.ComponentModel.DataAnnotations.Schema;3 4 namespace ContosoUniversity.Models5 {6 public class Course7 {8 [DatabaseGenerated(DatabaseGeneratedOption.None)]9 public int CourseID { get; set; }
10 public string Title { get; set; }
11 public int Credits { get; set; }
12
13 public ICollectionEnrollment Enrollments { get; set; }
14 }
15 } Enrollments属性是导航属性。 一个Course实体可以与任意数量的Enrollment实体相关。 创建数据库上下文 使得给定的数据模型与 Entity Framework 功能相协调的主类是数据库上下文类。 可以通过继承 Microsoft.EntityFrameworkCore.DbContext 类的方式创建此类。 在该类中你可以指定数据模型中包含哪些实体。 你还可以定义某些 Entity Framework 行为。 在此项目中将数据库上下文类命名为SchoolContext。 在项目文件夹中创建名为的文件夹Data。在Data文件夹创建名为SchoolContext.cs的类文件并将模板代码替换为以下代码 1 using ContosoUniversity.Models;2 using Microsoft.EntityFrameworkCore;3 4 namespace ContosoUniversity.Data5 {6 public class SchoolContext : DbContext7 {8 public SchoolContext(DbContextOptionsSchoolContext options) : base(options)9 {
10 }
11
12 public DbSetCourse Courses { get; set; }
13 public DbSetEnrollment Enrollments { get; set; }
14 public DbSetStudent Students { get; set; }
15 }
16 } View Code 此代码将为每个实体集创建DbSet属性。 在 Entity Framework 中实体集通常与数据表相对应具体实体与表中的行相对应。 在这里可以省略DbSetEnrollment和DbSetCourse语句实现的功能没有任何改变。 Entity Framework 会隐式包含这两个实体因为Student实体引用了Enrollment实体、Enrollment实体引用了Course实体。 当数据库创建完成后 EF 创建一系列数据表表名默认和DbSet属性名相同。 集合属性的名称一般使用复数形式但不同的开发人员的命名习惯可能不一样开发人员根据自己的情况确定是否使用复数形式。在最后一个 DbSet 属性之后添加以下代码对 DbContext 指定单数的表明来覆盖默认的表名。 1 protected override void OnModelCreating(ModelBuilder modelBuilder)
2 {
3 modelBuilder.EntityCourse().ToTable(Course);
4 modelBuilder.EntityEnrollment().ToTable(Enrollment);
5 modelBuilder.EntityStudent().ToTable(Student);
6 } View Code 用依赖注入注册上下文 ASP.NET Core 默认实现依赖注入。在应用程序启动过程通过依赖注入注册相关服务 例如 EF 数据库上下文。 需要这些服务的组件 如 MVC 控制器 可以通过向构造函数添加相关参数来获得对应服务。 若要将SchoolContext注册为一种服务打开Startup.cs并将以下代码添加到ConfigureServices方法中。 1 public void ConfigureServices(IServiceCollection services)
2 {
3 services.AddDbContextSchoolContext(options
4 options.UseSqlServer(Configuration.GetConnectionString(DefaultConnection)));
5
6 services.AddMvc();
7 } View Code 通过调用DbContextOptionsBuilder中的一个方法将数据库连接字符串在配置文件中的名称传递给上下文对象。 进行本地开发时 ASP.NET Core 配置系统在appsettings.json文件中读取数据库连接字符串。 添加using语句引用ContosoUniversity.Data和Microsoft.EntityFrameworkCore命名空间然后生成项目。 打开appsettings.json文件并添加连接字符串如下所示。 1 {2 ConnectionStrings: {3 DefaultConnection: Server(localdb)\\mssqllocaldb;DatabaseContosoUniversity1;Trusted_ConnectionTrue;MultipleActiveResultSetstrue4 },5 Logging: {6 IncludeScopes: false,7 LogLevel: {8 Default: Warning9 }
10 }
11 } 数据库连接字符串指定使用 SQL Server LocalDB 数据库。 LocalDB 是 SQL Server Express 数据库引擎的轻量级版本用于应用程序开发不在生产环境中使用。 LocalDB 作为按需启动并在用户模式下运行的轻量级数据库没有复杂的配置。 默认情况下 LocalDB 在C:/Users/user目录下创建.mdf数据库文件。 用测试数据初始化数据库 Entity Framework 已经为你创建了一个空数据库。在本部分中编写一个方法用于向数据库填充测试数据该方法会在数据库创建完成之后执行。 此处将使用EnsureCreated方法来自动创建数据库。 在Data文件夹中创建名为的新类文件DbInitializer.cs并且将模板代码替换为以下代码使得在需要时能创建数据库并向其填充测试数据。 1 using ContosoUniversity.Models;2 using System;3 using System.Linq;4 5 namespace ContosoUniversity.Data6 {7 public static class DbInitializer8 {9 public static void Initialize(SchoolContext context)
10 {
11 context.Database.EnsureCreated();
12
13 // Look for any students.
14 if (context.Students.Any())
15 {
16 return; // DB has been seeded
17 }
18
19 var students new Student[]
20 {
21 new Student{FirstMidNameCarson,LastNameAlexander,EnrollmentDateDateTime.Parse(2005-09-01)},
22 new Student{FirstMidNameMeredith,LastNameAlonso,EnrollmentDateDateTime.Parse(2002-09-01)},
23 new Student{FirstMidNameArturo,LastNameAnand,EnrollmentDateDateTime.Parse(2003-09-01)},
24 new Student{FirstMidNameGytis,LastNameBarzdukas,EnrollmentDateDateTime.Parse(2002-09-01)},
25 new Student{FirstMidNameYan,LastNameLi,EnrollmentDateDateTime.Parse(2002-09-01)},
26 new Student{FirstMidNamePeggy,LastNameJustice,EnrollmentDateDateTime.Parse(2001-09-01)},
27 new Student{FirstMidNameLaura,LastNameNorman,EnrollmentDateDateTime.Parse(2003-09-01)},
28 new Student{FirstMidNameNino,LastNameOlivetto,EnrollmentDateDateTime.Parse(2005-09-01)}
29 };
30 foreach (Student s in students)
31 {
32 context.Students.Add(s);
33 }
34 context.SaveChanges();
35
36 var courses new Course[]
37 {
38 new Course{CourseID1050,TitleChemistry,Credits3},
39 new Course{CourseID4022,TitleMicroeconomics,Credits3},
40 new Course{CourseID4041,TitleMacroeconomics,Credits3},
41 new Course{CourseID1045,TitleCalculus,Credits4},
42 new Course{CourseID3141,TitleTrigonometry,Credits4},
43 new Course{CourseID2021,TitleComposition,Credits3},
44 new Course{CourseID2042,TitleLiterature,Credits4}
45 };
46 foreach (Course c in courses)
47 {
48 context.Courses.Add(c);
49 }
50 context.SaveChanges();
51
52 var enrollments new Enrollment[]
53 {
54 new Enrollment{StudentID1,CourseID1050,GradeGrade.A},
55 new Enrollment{StudentID1,CourseID4022,GradeGrade.C},
56 new Enrollment{StudentID1,CourseID4041,GradeGrade.B},
57 new Enrollment{StudentID2,CourseID1045,GradeGrade.B},
58 new Enrollment{StudentID2,CourseID3141,GradeGrade.F},
59 new Enrollment{StudentID2,CourseID2021,GradeGrade.F},
60 new Enrollment{StudentID3,CourseID1050},
61 new Enrollment{StudentID4,CourseID1050},
62 new Enrollment{StudentID4,CourseID4022,GradeGrade.F},
63 new Enrollment{StudentID5,CourseID4041,GradeGrade.C},
64 new Enrollment{StudentID6,CourseID1045},
65 new Enrollment{StudentID7,CourseID3141,GradeGrade.A},
66 };
67 foreach (Enrollment e in enrollments)
68 {
69 context.Enrollments.Add(e);
70 }
71 context.SaveChanges();
72 }
73 }
74 } View Code 这段代码首先检查是否有学生数据在数据库中如果没有的话就可以假定数据库是新建的然后使用测试数据进行填充。代码中使用数组存放测试数据而不是使用ListT集合是为了优化性能。 在Program.cs修改Main方法使得在应用程序启动时能执行以下操作 从依赖注入容器中获取数据库上下文实例。调用 seed 方法将上下文传递给它。Seed 方法完成此操作时释放上下文。 1 using ContosoUniversity.Data;2 using Microsoft.AspNetCore;3 using Microsoft.AspNetCore.Hosting;4 using Microsoft.Extensions.DependencyInjection;5 using Microsoft.Extensions.Logging;6 using System;7 8 namespace ContosoUniversity9 {
10 public class Program
11 {
12 public static void Main(string[] args)
13 {
14 var host CreateWebHostBuilder(args).Build();
15 using (var scope host.Services.CreateScope())
16 {
17 var services scope.ServiceProvider;
18 try
19 {
20 var context services.GetRequiredServiceSchoolContext();
21 DbInitializer.Initialize(context);
22 }
23 catch (Exception ex)
24 {
25 var logger services.GetRequiredServiceILoggerProgram();
26 logger.LogError(ex, An error occurred while seeding the database.);
27 }
28 }
29 host.Run();
30 }
31
32 public static IWebHostBuilder CreateWebHostBuilder(string[] args)
33 WebHost.CreateDefaultBuilder(args)
34 .UseStartupStartup();
35 }
36 } View Code 现在首次运行该应用程序创建数据库并使用测试数据作为种子数据。 每当你更改你的数据模型你可以删除数据库、 更新你的 Initialize 方法然后使用上述方式更新新数据库。 在之后的教程中你将了解如何在数据模型更改时只需修改数据库而无需删除重建数据库。 创建控制器和视图 用 Visual Studio 中的基架引擎添加一个 MVC 控制器和使用 EF 来查询和保存数据的视图。 CRUD 操作方法和视图的自动创建被称为基架。 基架与代码生成不同基架的代码是一个起点您可以修改基架以满足自己需求而你通常无需修改生成的代码。 当你需要自定义生成代码时你使用一部分类或需求发生变化时重新生成代码。 右键单击解决方案资源管理器中的Controllers文件夹选择添加 新搭建的基架项目。 在添加基架的对话框中 选择视图使用 Entity Framework 的 MVC 控制器 单击添加 在添加控制器对话框中 在模型类选择Student 在数据上下文类选择SchoolContext 使用StudentsController作为默认名字 单击添加 当你单击添加后Visual Studio 基架引擎创建StudentsController.cs文件和一组对应于控制器的视图 (.cshtml文件) 。 (如果你之前手动创建数据库上下文基架引擎还可以自动创建。 你可以在添加控制器对话框中单击右侧的加号框数据上下文类来指定在一个新上下文类。然后Visual Studio 将创建你的DbContext控制器和视图类。) 你会注意到控制器采用SchoolContext作为构造函数参数。 public class StudentsController : Controller{private readonly SchoolContext _context;public StudentsController(SchoolContext context){_context context;} ASP.NET 依赖注入机制将会处理传递一个SchoolContext实例到控制器。 控制器包含Index操作方法用于显示数据库中的所有学生。 该方法从学生实体集中获取学生列表学生实体集则是通过读取数据库上下文实例中的Students属性获得 public async TaskIActionResult Index()
{return View(await _context.Students.ToListAsync());
} Views/Students/Index.cshtml视图使用table标签显示此列表 1 model IEnumerableContosoUniversity.Models.Student2 3 {4 ViewData[Title] Index;5 }6 7 h2Index/h28 9 p
10 a asp-actionCreateCreate New/a
11 /p
12 table classtable
13 thead
14 tr
15 th
16 Html.DisplayNameFor(model model.LastName)
17 /th
18 th
19 Html.DisplayNameFor(model model.FirstMidName)
20 /th
21 th
22 Html.DisplayNameFor(model model.EnrollmentDate)
23 /th
24 th/th
25 /tr
26 /thead
27 tbody
28 foreach (var item in Model) {
29 tr
30 td
31 Html.DisplayFor(modelItem item.LastName)
32 /td
33 td
34 Html.DisplayFor(modelItem item.FirstMidName)
35 /td
36 td
37 Html.DisplayFor(modelItem item.EnrollmentDate)
38 /td
39 td
40 a asp-actionEdit asp-route-iditem.IDEdit/a |
41 a asp-actionDetails asp-route-iditem.IDDetails/a |
42 a asp-actionDelete asp-route-iditem.IDDelete/a
43 /td
44 /tr
45 }
46 /tbody
47 /table View Code 按 CTRL F5 来运行该项目或从菜单选择调试 开始执行不调试。 单击学生选项卡以查看DbInitializer.Initialize插入的测试的数据。 你将看到Student选项卡链接在页的顶部或在单击右上角后的导航图标中具体显示在哪里取决于浏览器窗口宽度。 约定 由于 Entity Framwork 有一定的约束条件你只需要按规则编写很少的代码就能够创建一个完整的数据库 DbSet类型的属性用作表名。 实体未被DbSet属性引用实体类名称用作表名称。 实体属性名称用于列名称。 ID 或 classnameID 命名的实体属性被识别为主键属性。 如果属性名为 导航属性名 主键名将被解释为外键属性 (例如StudentID对应Student导航属性Student实体的主键是ID所以StudentID被解释为外键属性). 此外也可以将外键属性命名为 主键属性名 (例如EnrollmentID由于Enrollment实体的主键是EnrollmentID因此被解释为外键)。 约定行为可以被重写。 例如设置列名称和将任何属性设置为主键或外键。 异步代码 异步编程是 ASP.NET Core 和 EF Core 的默认模式。 Web 服务器的可用线程是有限的而在高负载情况下的可能所有线程都被占用。 当发生这种情况的时候服务器就无法处理新请求直到线程被释放。 使用同步代码时可能会出现多个线程被占用但不能执行任何操作的情况因为它们正在等待 I/O 完成。 使用异步代码时当进程正在等待 I/O 完成服务器可以将其线程释放用于处理其他请求。 因此异步代码使得服务器更有效地使用资源并且该服务器可以无延迟地处理更多流量。 异步代码在运行时会引入的少量开销在低流量时对性能的影响可以忽略不计但在针对高流量情况下潜在的性能提升是可观的。 在下面的代码中async关键字TaskT返回值await关键字和ToListAsync方法使代码异步执行。 public async TaskIActionResult Index()
{return View(await _context.Students.ToListAsync());
} async关键字用于告知编译器该方法主体将生成回调并自动创建TaskIActionResult返回对象。 返回类型TaskIActionResult表示正在进行的工作返回的结果为IActionResult类型。 await关键字会使得编译器将方法拆分为两个部分。 第一部分是以异步方式结束已启动的操作。 第二部分是当操作完成时注入调用回调方法的地方。 ToListAsync是由ToList方法的的异步扩展版本。 你使用 Entity Framework 编写异步代码时的一些注意事项 只有导致查询或发送数据库命令的语句才能以异步方式执行。 包括 ToListAsync SingleOrDefaultAsync和SaveChangesAsync。 不包括操作IQueryable的语句如var students context.Students.Where(s s.LastName Lilo)。 EF 上下文是线程不安全的 请勿尝试并行执行多个操作。 当调用异步 EF 方法时始终使用await关键字。 如果你想要利用异步代码的性能优势请确保你所使用的任何库和包在它们调用导致 Entity Framework 数据库查询方法时也使用异步。 总结 现已创建了一个使用 Entity Framework Core 和 SQL Server Express LocalDB 来存储和显示数据的简单应用程序。 在下一篇中将介绍如何执行基本的 CRUD 创建、 读取、 更新、 删除 操作。 ***************************** *** Keep learning and growing. *** *****************************转载于:https://www.cnblogs.com/gangle/p/9190287.html