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

news2025/1/14 4:06:32

本篇介绍原书的第 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"
                };

                // Category
                var 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=398940
        public 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=398940
        public 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.coloradmin.cn/o/1623439.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【黑马头条】-day11热点文章实时计算-kafka-kafkaStream-Redis

文章目录 今日内容1 实时流式计算1.1 应用场景1.2 技术方案选型 2 Kafka Stream2.1 概述2.2 KafkaStream2.3 入门demo2.3.1 需求分析2.3.2 实现2.3.2.1 添加依赖2.3.2.2 创建快速启动&#xff0c;生成kafka流2.3.2.3 修改生产者2.3.2.4 修改消费者2.3.2.5 测试 2.4 SpringBoot集…

机器学习作业3____决策树(CART算法)

目录 一、简介 二、具体步骤 样例&#xff1a; 三、代码 四、结果 五、问题与解决 一、简介 CART&#xff08;Classification and Regression Trees&#xff09;是一种常用的决策树算法&#xff0c;可用于分类和回归任务。这个算法由Breiman等人于1984年提出&#xff0c;它…

Clion连接MySQL数据库:实现C/C++语言与MySQL交互

确保你的电脑里已经有了MySQL。 1、找到MySQL的目录 2、进入lib目录 3、复制libmysql.dll和libmysql.lib文件 4、将这俩文件粘贴到你的clion项目的cmake-build-debug目录下 如果不是在这个目录下&#xff0c;运行时会出以下错误报错&#xff1a; 进程已结束&#xff0c;退…

火绒安全的应用介绍

火绒安全软件是一款集成了杀毒、防御和管控功能的安全软件&#xff0c;旨在为用户提供全面的计算机安全保障。以下是火绒安全软件的一些详细介绍&#xff1a; 系统兼容性强&#xff1a;该软件支持多种操作系统&#xff0c;包括Windows 11、Windows 10、Windows 8、Windows 7、…

AI预测福彩3D第9套算法实战化测试第3弹2024年4月25日第3次测试

今天继续进行新算法的测试&#xff0c;今天是第3次测试。好了&#xff0c;废话不多说了&#xff0c;直接上图上结果。 2024年4月25日福彩3D预测结果 6码定位方案如下&#xff1a; 百位&#xff1a;6、4、3、7、2、8 十位&#xff1a;8、4、9、3、1、0 个位&#xff1a;7、6、9、…

Linux进程间通信 管道系列: 利用管道实现进程池(匿名和命名两个版本)

Linux进程间通信 管道系列: 利用管道实现进程池[匿名和命名两个版本] 一.匿名管道实现进程池1.池化技术2.搭架子3.代码编写1.创建子进程1.利用命令行参数传入创建几个子进程2.创建管道和子进程(封装Channel类)1.先描述2.在组织3.开始创建 2.封装MainProcess类3.控制子进程1.封装…

无限滚动分页加载与下拉刷新技术探析:原理深度解读与实战应用详述

滚动分页加载&#xff08;也称为无限滚动加载、滚动分页等&#xff09;是一种常见的Web和移动端应用界面设计模式&#xff0c;用于在用户滚动到底部时自动加载下一页内容&#xff0c;而无需点击传统的分页按钮。这种设计旨在提供更加流畅、连续的浏览体验&#xff0c;减少用户交…

人耳的七个效应

1、掩蔽效应 • 人们在安静环境中能够分辨出轻微的声音&#xff0c;即人耳对这个声音的听域很低&#xff0c;但在嘈杂的环境中轻微的声音就会被淹没掉&#xff0c;这时将轻微的声音增强才能听到。 • 这种在聆听时&#xff0c;一个声音的听阈因另一声音的出现而提高的现象&…

ThinkPad E14 Gen 4,R14 Gen 4,E15 Gen 4(21E3,21E4,21E5,21E6,21E7)原厂Win11系统恢复镜像下载

lenovo联想ThinkPad笔记本电脑原装出厂Windows11系统安装包&#xff0c;恢复出厂开箱状态一模一样 适用型号&#xff1a;ThinkPad E14 Gen 4,ThinkPad R14 Gen 4,ThinkPad E15 Gen 4 (21E3,21E4,21E5,21E6,21E7) 链接&#xff1a;https://pan.baidu.com/s/1QRHlg2yT_RFQ81Tg…

服务部署后出错怎么快速调试?试试JDWP协议

前言 原文链接&#xff1a;教你使用 JDWP 远程调试服务 在我们日常开发工作中&#xff0c;经常会遇到写好的代码线上出了问题&#xff0c;但是本地又无法复现&#xff0c;看着控制台输出的日志恨自己当初没有多打几条日志&#xff0c;然后追着日志一条一条查&#xff0c;不说…

安装 Nginx 的三种方式

通过 Nginx 源码安装需要提前准备的内容&#xff1a; GCC 编译器 Nginx 是使用 C 语言编写的程序&#xff0c;因此想要运行 Nginx 就需要安装一个编译工具 GCC 就是一个开源的编译器集合&#xff0c;用于处理各种各样的语言&#xff0c;其中就包含了 C 语言 使用命令 yum i…

python基础语法--列表

一、列表的概念 列表&#xff08;List&#xff09;是一种有序、可变、允许重复元素的数据结构。列表用于存储一组相关的元素&#xff0c;并且可以根据需要动态地进行增加、删除、修改和访问。以下是列表的主要特点和操作&#xff1a; 有序性&#xff1a; 列表中的元素是按照它…

工作与生活,如何找到平衡点,实现双赢?(2个简单工具答案一目了然)

前言 很多 35岁左右上有老下有小的程序员会陷入一个瓶颈期&#xff0c;在工作上想努力多赚钱&#xff0c;但是每天回到家 23 点&#xff0c;老婆孩子早已熟睡。好不容易周末有点休息时间&#xff0c;但是一个电话接一个&#xff0c;由于是生产问题还不得不接。 那么职场人应该如…

激活IDM下载器并配置百度网盘

前言&#xff1a; 最近想下载一些软件&#xff0c;奈何不充钱的百度网盘的速度实在太慢了&#xff0c;不到一个G的文件夹奈何下了一晚上&#xff0c;只能重新找一下idm的下载了。 但是idm的正版是需要收费的&#xff0c;所以有白嫖党的破解版就横空出世了。 正文&#xff1a…

【目标跟踪】ByteTrack详解与代码细节

文章目录 一、前言二、代码详解2.1、新起航迹2.2、预测2.3、匹配2.4、结果发布2.5、总结 三、流程图四、部署 一、前言 论文地址&#xff1a;https://arxiv.org/pdf/2110.06864.pdf git地址&#xff1a;https://github.com/ifzhang/ByteTrack ByteTrack 在是在 2021 年 10 月…

OpenAIGPT-4.5提前曝光?

OpenAI GPT-4.5的神秘面纱&#xff1a;科技界的震撼新篇章 在人工智能的世界里&#xff0c;每一次技术的飞跃都不仅仅是一次更新&#xff0c;而是对未来无限可能的探索。近日&#xff0c;科技巨头OpenAI似乎再次站在了这场革命的前沿&#xff0c;其潜在的新产品——GPT-4.5 Tur…

Https协议原理剖析【计算机网络】【三种加密方法 | CA证书 】

目录 一&#xff0c;fidler工具 前提知识 二&#xff0c;Https原理解析 1. 中间人攻击 2. 常见的加密方式 1&#xff09;. 对称加密 2&#xff09;. 非对称加密 对称加密 4&#xff09;. CA证书 1. 数据摘要 3. 数字签名 CA证书 理解数据签名 存在的安全疑问&am…

ubuntu ROS1 C++下使用免安装eigen库的方法

1、eigen库的定义及头文件介绍 Eigen是一个高层次的C 库&#xff0c;有效支持线性代数&#xff0c;矩阵和矢量运算&#xff0c;数值分析及其相关的算法。 2、获取eigen库安装包 下载地址&#xff1a;eigen库官网 &#xff0c;如下图所示&#xff1a; 下载最新版tar.bz2即可&…

嵌入式Linux driver开发实操(二十三):ASOC

ASoC的结构及嵌入到Linux音频框架 ALSA片上系统(ASoC)层的总体项目目标是为嵌入式片上系统处理器(如pxa2xx、au1x00、iMX等)和便携式音频编解码器提供更好的ALSA支持。在ASoC子系统之前,内核中对SoC音频有一些支持,但它有一些局限性: ->编解码器驱动程序通常与底层So…

甘特图是什么?如何利用其优化项目管理流程?

甘特图是项目管理软件中十分常见的功能&#xff0c;可以说每一个项目经理都要学会使用甘特图才能更好的交付项目。什么是甘特图&#xff1f;甘特图用来做什么&#xff1f;简单来说一种将项目任务与时间关系直观表示的图表&#xff0c;直观地展示了任务进度和持续时间。 一、甘特…