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

本篇介绍原书的第 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版)》学习笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/574211.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt Quick centerIn和fill 的用法

1&#xff09;Qt Quick centerIn和fill 的用法&#xff1a; import QtQuick 2.5 Rectangle { width:300; height:200; Rectangle { color: "blue"; anchors.fill: parent; border.width: 6; border.co…

详解工业网关在线探测功能及用途

工业网关专为工业物联网应用设计&#xff0c;可实现包括不同通讯协议之间的兼容和转换&#xff0c;提供软硬件加密保障工业数据安全传输&#xff0c;发挥强大算力实现数据边缘预处理&#xff0c;联动联调工业网络设备实现高效协同等。在线探测功能是佰马工业网关的一项重要功能…

unity学习(89)——unity塞满c盘!--删除editor下的log文件

卸了一个视频后强制续命打开详细信息&#xff1a; 这个再往下找也是没用的&#xff01; 显示隐藏文件夹后&#xff01;执行如下操作&#xff01; 30个g&#xff01; 其中unity占23g editer占了21g 删除C:\Users\王栋林\AppData\Local\Unity\Editor下的log文件 恢复到之前的水…

使用 Flask 和 WTForms 构建一个用户注册表单

在这篇技术博客中&#xff0c;我们将使用 Flask 和 WTForms 库来构建一个用户注册表单。我们将创建一个简单的 Flask 应用&#xff0c;并使用 WTForms 定义一个注册表单&#xff0c;包括用户名、密码、确认密码、邮箱、性别、城市和爱好等字段。我们还将为表单添加验证规则&…

【C 数据结构】图

文章目录 【 1. 基本原理 】1.1 无向图1.2 有向图1.3 基本知识 【 2. 图的存储结构 】2.1 完全图2.2 稀疏图和稠密图2.3 连通图2.3.1 (普通)连通图连通图 - 无向图非连通图 的 连通分量 2.3.2 强连通图强连通图 - 有向图非强连通有向图 的 强连通分量 2.3.3 生成树 - 连通图2.3…

美区视频带货“一哥”,一周销量狂干三十万美金!

“超店有数显示&#xff0c;Tybuggy上周带货狂揽34.3万美金&#xff0c;超出第二名近30倍。” TikTok风波再起&#xff0c;4月17日&#xff0c;美众议院推出援乌援以军事议案&#xff0c;值得注意的是&#xff0c;TikTok剥离法案被“打包”夹带其中&#xff0c;以此加大再参议…

LLM应用实战:当KBQA集成LLM(二)

1. 背景 又两周过去了&#xff0c;本qiang~依然奋斗在上周提到的项目KBQA集成LLM&#xff0c;感兴趣的可通过传送门查阅先前的文章《LLM应用实战&#xff1a;当KBQA集成LLM》。 本次又有什么更新呢&#xff1f;主要是针对上次提到的缺点进行优化改进。主要包含如下方面&#…

【Linux笔记】基本指令(一)

一道残阳铺水中 半江瑟瑟半江红 目录 Linux基本指令 罗列目录内容&#xff1a;ls 指令 显示当前目录位置信息&#xff1a;pwd 指令 切换工作目录&#xff1a;cd 指令 创建文件修改时间戳&#xff1a;touch指令 创建空目录&#xff1a;mkdir指令 删除空目录&#xff1a;rmdir指…

1.3K Star我上位机项目中用了这个开源项目

软件介绍 ClientServerProject的软件是一款基于C-S&#xff08;客户端-服务器&#xff09;架构的通用开发框架&#xff0c;为中小型系统的快速开发提供强大的支持。该框架由服务端、客户端以及公共组件三部分组成&#xff0c;不仅提供了基础的账户管理、版本控制、软件升级、公…

输入法重大漏洞曝光,仅华为幸免,近10亿用户受影响

近日&#xff0c;Citizenlab研究人员调查了多家厂商的输入法应用安全漏洞并报告称&#xff1a;除华为以外&#xff0c;百度、荣耀、科大讯飞、OPPO、三星、腾讯、Vivo和小米等供应商的九款应用程序中有八款均存在安全漏洞。 随着用户规模的不断增长&#xff0c;云输入法应用的…

kubernetes中DaemonSet控制器

一、概念 使用DaemonSet控制器&#xff0c;相当于在节点上启动了一个守护进程。通过DaemonSet控制器可以确保在每个节点上运行Pod的一个副本。如果有心的node节点加入集群&#xff0c;则DaemonSet控制器会自动给新加入的节点增加一个Pod的副本&#xff1b;反之&#xff0c;当有…

GPT的全面历史和演变:从GPT-1到GPT-4

人工智能新篇章&#xff1a;GPT-4与人类互动的未来&#xff01; 本文探讨了生成式预训练 Transformer (GPT) 的显着演变&#xff0c;提供了从开创性的 GPT-1 到复杂的 GPT-4 的旅程。 每次迭代都标志着重大的技术飞跃&#xff0c;深刻影响人工智能领域以及我们与技术的互动。 我…

vmware虚拟机网络“桥接模式”与“NAT模式”的联网原理及linux环境下IP配置指引

一、vmware虚拟机网络“桥接模式”与“NAT模式”的区别 选中虚拟机》设置》网络适配器&#xff0c;打开虚拟机设置面板 我们看到网络连接处有多个选项&#xff0c;今天良哥通过试验告诉你“桥接模式”和“NAT模式”的联网原理、区别及两种模式下IP地址配置的详细方法。 桥接模…

YOLOv9改进策略 | 添加注意力篇 | LSKAttention大核注意力机制助力极限涨点 (附多个位置添加教程)

一、本文介绍 本文给大家带来的改进机制是LSKAttention大核注意力机制应用于YOLOv9。它的主要思想是将深度卷积层的2D卷积核分解为水平和垂直1D卷积核&#xff0c;减少了计算复杂性和内存占用。接着&#xff0c;我们介绍将这一机制整合到YOLOv9的方法&#xff0c;以及它如何帮…

面试经典150题——路径总和

​ 1. 题目描述 2. 题目分析与解析 2.1 思路一 注意题目的关键点&#xff1a;判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;起点是root&#xff0c;终点是叶子节点。 那么我们就可以从根节点按照层序遍历的方式&#xff0c;从根节点从根到 叶子不断对路径进行加…

MPC的横向控制与算法仿真实现

文章目录 1. 引言2. 模型预测控制&#xff08;MPC&#xff09;2.1 基础知识2.2 MPC的整体流程2.3 MPC的设计求解 3. 车辆运动学MPC设计4. 算法和仿真实现 1. 引言 随着智能交通系统和自动驾驶技术的发展&#xff0c;车辆的横向控制成为了研究的热点。横向控制指的是对车辆在行…

vue3环境搭建

环境准备&#xff1a; node环境(node.js官网)npm环境 上述两个环境存在版本要求所以安装最新的靠谱&#xff08;旧的环境存在不支持现象&#xff09; windows电脑 安装完node.js会带有npm mac电脑本身自带node和npm&#xff0c;但是需要升级 进入到你想创建前端项目的文件夹:…

C++初识内存管理和模版

目录 前言 1.C/C内存分布 2. C的内存管理方式 2.1 new/delete操作内置类型 2. new和delete操作自定义类型 3. operator new和operator delete函数 4. new和delete的实现原理 4.1 内置类型 4.2 自定义类型 5. malloc/free和new/delete的区别 6. 初识模版 6.1 泛型编…

【python笔记】datafram的时间动态可视化 pyecharts地图

import pandas as pd# 假设DataFrame是这样的&#xff1a; df pd.DataFrame({ year: [2014, 2015, 2016, 2014, 2015, 2016, 2014, 2015, 2016], province: [广东省, 广东省, 河南省, 湖南省, 北京市, 北京市, 上海市, 新疆维吾尔自治区, 上海市], values: [100, 150, 75…

井字棋源码(网络线程池版)

源码链接&#xff1a;game 效果可能没有那么好&#xff0c;大家可以给点建议。 效果展示 game.h #include <stdio.h> #include <stdlib.h> #include <time.h>#define ROW 3 #define COL 3void InitBoard(char board[ROW][COL], int row, int col) {int i…