ASP.NET Core 3 高级编程(第8版) 学习笔记 03

ops/2024/10/19 11:51:39/

本篇介绍原书的第 18 章,为 19 章 Restful Service 编写基础代码。本章实现了如下内容:
1)使用 Entity Framework Core 操作 Sql Server 数据库
2)Entity Framework Core 数据库迁移和使用种子数据的方法
3)使用中间件 (middleware) 来配置请求管道 (request pipeline)

Nuget 包

为了运行本章代码,需要下面的三个包:

Microsoft.EntityFrameworkCore.SqlServer --version 3.1.1
Microsoft.EntityFrameworkCore.Design --version 3.1.1
Microsoft.EntityFrameworkore.Tool --version 3.1.1

数据模型

创建 Products, Category 和 Suppliers 三个实体模型:

namespace WebApp.Models
{public class Category{public long CategoryId { get; set; }public string Name { get; set; }public IEnumerable<Product> Products { get; set; }}
}
namespace WebApp.Models
{public class Supplier{public long SupplierId { get; set; }public string Name { get; set; }public string City { get; set; }public IEnumerable<Product> Products { get; set; }}
}
namespace WebApp.Models
{public class Product{public long ProductId { get; set; }public string Name { get; set; }public decimal Price { get; set; }  public long CategoryId { get; set; }public Category Category { get; set; }public long SupplierId { get; set; }public Supplier Supplier { get; set; }  }
}

创建 DbContext 类

using Microsoft.EntityFrameworkCore;namespace WebApp.Models
{public class DataContext : DbContext{public DataContext(DbContextOptions<DataContext> opts) : base(opts) { }public DbSet<Product> Products { get; set; }public DbSet<Category> Categories { get; set; }public DbSet<Supplier> Suppliers { get; set; }}
}

种子数据

using Microsoft.EntityFrameworkCore;
using System.Linq;namespace WebApp.Models
{public class SeedData{public static void SeedDatabase(DataContext context){context.Database.Migrate();// 只有在空的时候才填充数据if (context.Products.Count() == 0 && context.Suppliers.Count() == 0 && context.Categories.Count() == 0) {// 供应商var s1 = new Supplier{Name = "Splash Dudes",City = "San Jose"};var s2 = new Supplier{Name = "Soccer Town",City = "Chicago"};var s3 = new Supplier { Name = "Chess Co",City = "New York"};// Categoryvar c1 = new Category { Name = "Watersports" };var c2 = new Category { Name = "Soccer" };var c3 = new Category { Name = "Chess" };context.Products.AddRange(new Product { Name = "Kayak", Price = 275, Category = c1, Supplier = s1} ,new Product { Name = "LifeJacket", Price = 48.95m, Category = c1, Supplier = s1} , new Product { Name = "Soccer ball", Price = 19.50m, Category= c2, Supplier = s2} ,new Product { Name = "Corner Flags", Price = 34.95m, Category= c2, Supplier = s2} ,new Product { Name = "Stadium", Price = 79500, Category= c2, Supplier = s2} ,new Product { Name = "Thinking Cap", Price = 16, Category= c3, Supplier = s3} ,new Product { Name = "Unsteady Chair", Price = 29.95m, Category= c3, Supplier = s3} ,new Product { Name = "Human Chess Board", Price = 75, Category= c3, Supplier = s3} ,new Product { Name = "Bling-Bling King", Price = 1200, Category= c3, Supplier = s3} );context.SaveChanges();}}}
}

数据库连接字符串

使用 Sql Server LocalDB,将数据库连接字符串写在 appsettings.json 文件。

{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information","Microsoft.EntityFrameworkCore": "Information"}},"AllowedHosts": "*","ConnectionStrings" : {"ProductConnection" : "Server=(localdb)\\MSSQLLocalDB;Database=Products;MultipleActiveResultSets=True"}
}

配置 Entity Framework Core

在 Startup.cs 的 Configure() 方法中进行配置:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApp.Models;namespace WebApp
{public class Startup{public Startup(IConfiguration config){Configuration = config;}public IConfiguration Configuration { get; set; }// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){services.AddDbContext<DataContext>(opts =>{opts.UseSqlServer(Configuration["ConnectionStrings:ProductConnection"]);//opts.EnableSensitiveDataLogging(true);});}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext context){         if (env.IsDevelopment()) {app.UseDeveloperExceptionPage();}app.UseRouting();app.UseEndpoints(endpoints =>{endpoints.MapGet("/", async context =>{await context.Response.WriteAsync("Hello World!");});});SeedData.SeedDatabase(context);}}
}

注意:Configure() 方法在默认代码的基础上增加了 DbContext 参数,目的是启动的时候自动运行向数据库添加种子数据。

数据库迁移

打开 Package Manager Console (Tools > Nuget Package Manager > Package Manager Console),运行下面两个命令:

Add-migration initDatabae
update-database

Add-migration 命令将创建迁移脚本
update-database 将未提交的变化提交到数据库。

运行之后,使用 SQL Server Object Explorer (View > SQL Server Object Explore)可以看到,数据库和表都已经正确创建。

使用中间件配置请求管道

希望实现的效果是 Http Get 请求 /test 能返回三张表的数据条数。

创建 TestMiddleware 中间件:

using Microsoft.AspNetCore.Http;
using System.Linq;
using System.Threading.Tasks;
using WebApp.Models;namespace WebApp
{public class TestMiddleware{private RequestDelegate nextDelegate;public TestMiddleware(RequestDelegate nextDelegate){this.nextDelegate = nextDelegate;}public async Task Invoke(HttpContext context, DataContext dataContext){if (context.Request.Path == "/test") {await context.Response.WriteAsync($"There are {dataContext.Products.Count()} prodcts.\n");await context.Response.WriteAsync($"There are {dataContext.Categories.Count()} categories.\n");await context.Response.WriteAsync($"There are {dataContext.Suppliers.Count()} suppliers.\n");} else {await nextDelegate(context);}}}
}

在 Startup.cs 文件中配置中间件。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApp.Models;namespace WebApp
{public class Startup{public Startup(IConfiguration config){Configuration = config;}public IConfiguration Configuration { get; set; }// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){services.AddDbContext<DataContext>(opts =>{opts.UseSqlServer(Configuration["ConnectionStrings:ProductConnection"]);//opts.EnableSensitiveDataLogging(true);});}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext context){         if (env.IsDevelopment()) {app.UseDeveloperExceptionPage();}app.UseRouting();app.UseMiddleware<TestMiddleware>();app.UseEndpoints(endpoints =>{endpoints.MapGet("/", async context =>{await context.Response.WriteAsync("Hello World!");});});SeedData.SeedDatabase(context);}}
}

源码

pro asp.net core 3 notes: 《ASP.NET Core 3高级编程(第8版)》学习笔记


http://www.ppmy.cn/ops/15737.html

相关文章

学习MinSTM32F103的V3版本(已停产)—— 跑马灯(寄存器版本)

实现过程&#xff1a; 1.首先要说的是这里用到的keil5软件中新建项目中选取的板子是STM32F103RC&#xff08;T6&#xff09;&#xff0c;流程如下&#xff1a; 先在你想创建的盘下创建一个新的文件&#xff08;一定要在文件管理器中先创建&#xff0c;如果直接在keil中创建的…

Confluence 快捷键大揭秘:提高效率的小窍门

使用 Confluence 快捷键的好处有&#xff1a; 1.提高工作效率&#xff1b; 2.更流畅地进行编辑、导航和管理操作&#xff1b; 3.减少误操作&#xff1b; 4.展现专业水平。 更多精彩内容&#xff1a; 成为 Jira 大师&#xff1a;效率达人的必备秘诀 Jira Cloud 项目管理专栏 PMO…

网络协议深度解析:SSL、 TLS、HTTP和 DNS(C/C++代码实现)

在数字化时代&#xff0c;网络协议构成了互联网通信的基石。SSL、TLS、HTTP和DNS是其中最关键的几种&#xff0c;它们确保了我们的数据安全传输、网页的正确显示以及域名的正常解析。 要理解这些协议&#xff0c;首先需要了解网络分层模型。SSL和TLS位于传输层之上&#xff0c…

C# 通过阿里云 API 实现企业营业执照OCR识别

目录 应用场景 关于阿里云企业营业执照OCR识别 开发运行环境 类设计 类属性 类方法 实现代码 创建 Company 类 调用举例 小结 应用场景 企业营业执照犹如个人的身份证一样&#xff0c;是​​​​​​​工商管理机关发给企业、个体经营者的准许从事某项生产活动的凭…

三维点云处理-KDTree和Octree

点云数据主要是表征目标表面的海量点集合&#xff0c;并不具备传统实体网格数据的集合拓扑信息。因此&#xff0c;如何建立离散点间的拓扑关系&#xff0c;实现基于邻域关系的快速查找也是点云数据处理中比较核心的问题。对于一维数据来说&#xff0c;典型的树形存储结构如Bina…

探索常见经典目标检测算法:从YOLO到Faster R-CNN

目标检测是计算机视觉领域中的重要任务之一&#xff0c;它旨在从图像或视频中检测出目标的位置和类别。随着深度学习技术的发展&#xff0c;许多经典的目标检测算法相继出现&#xff0c;其中包括YOLO&#xff08;You Only Look Once&#xff09;、Faster R-CNN&#xff08;Regi…

教授 Avi Wigderson荣获2023年图灵奖

2023年图灵奖&#xff0c;最近刚刚颁给普林斯顿数学教授 Avi Wigderson&#xff01;作为理论计算机科学领域的领军人物&#xff0c;他对于理解计算中的随机性和伪随机性的作用&#xff0c;作出了开创性贡献。 Avi Wigderson因其在计算复杂性理论、随机性与算法等领域的开创性贡…

python学习笔记(集合)

知识点思维导图 # 直接使用{}进行创建 s{10,20,30,40} print(s)# 使用内置函数set()创建 sset() print(s)# 创建一个空的{}默认是字典类型 s{} print(s,type(s))sset(helloworld) print(s) sset([10,20,30]) print(s) s1set(range(1,10)) print(s1)print(max:,max(s1)) print(m…