From 29a4d9bcb355388619e64a0d359a5a4fd2d81039 Mon Sep 17 00:00:00 2001 From: xuchen <2367862934@qq.com> Date: Fri, 7 Jun 2024 11:27:17 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0520-.NET Core\345\222\214ASP.NET Core.md" | 48 ++++ ...10\345\222\214\351\241\271\347\233\256.md" | 18 ++ .../20240523-Startup\347\261\273.md" | 111 +++++++++ ...34\272\357\274\210Web Host\357\274\211.md" | 97 ++++++++ ...17\345\222\214\350\267\257\347\224\261.md" | 55 +++++ ...50\345\222\214\346\227\245\345\277\227.md" | 85 +++++++ ...13\346\225\260\346\215\256\345\272\223.md" | 28 +++ .../20240531-\346\216\245\345\217\243.md" | 56 +++++ ...36\347\216\260\351\203\250\345\210\206.md" | 73 ++++++ ...06\345\220\210\346\216\245\345\217\243.md" | 24 ++ ...56\346\224\271\346\216\245\345\217\243.md" | 115 ++++++++++ ...0240607-\345\274\225\345\205\245EFCore.md" | 213 ++++++++++++++++++ 12 files changed, 923 insertions(+) create mode 100644 "\350\256\270\346\231\250/20240603-\351\241\271\347\233\256\345\256\236\347\216\260\351\203\250\345\210\206.md" create mode 100644 "\350\256\270\346\231\250/20240604-\345\270\270\350\247\201\351\233\206\345\220\210\346\216\245\345\217\243.md" create mode 100644 "\350\256\270\346\231\250/20240606-\345\256\214\346\210\220\345\233\276\344\271\246\347\232\204\346\226\260\345\242\236\343\200\201\344\277\256\346\224\271\346\216\245\345\217\243.md" create mode 100644 "\350\256\270\346\231\250/20240607-\345\274\225\345\205\245EFCore.md" diff --git "a/\350\256\270\346\231\250/20240520-.NET Core\345\222\214ASP.NET Core.md" "b/\350\256\270\346\231\250/20240520-.NET Core\345\222\214ASP.NET Core.md" index 7095038..574d9d2 100644 --- "a/\350\256\270\346\231\250/20240520-.NET Core\345\222\214ASP.NET Core.md" +++ "b/\350\256\270\346\231\250/20240520-.NET Core\345\222\214ASP.NET Core.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## .NET Core和ASP.NET Core ### 1.什么是.NET Core? @@ -43,3 +44,50 @@ ASP.NET Core是免费、开源、高性能且跨平台的Web框架,用来构 ### 7.创建一个API项目 要创建一个ASP.NET Core Web API应用程序,可以使用Visual Studio,也可以使用ual Studio Core和JetBrains Rider等跨平台开发工具 +======= +## .NET Core和ASP.NET Core + +### 1.什么是.NET Core? +.NET Core框架是免费、开源、跨平台的,可以运行在Linux、Macos、Windows平台下。 + +### 2. .NET Core包含以下几部分内容: +- CoreCLR +- CoreFX +- Roslyn变异器 +- .NET Core CLI工具 + + +### 3. .NET Core的优点 +- 支持独立部署,不相互影响; +- 彻底模块化; +- 没有历史包袱,运行效率高; +- 不依赖于IIS; +- 跨平台; +- 符合现代开发理念:依赖注入、单元测试等。 + +### 4.什么是ASP.NET Core? +ASP.NET Core是免费、开源、高性能且跨平台的Web框架,用来构建Web应用程序。ASP.NET Core能够运行在多个操作系统平台上,包括Windows、macOS和Linux系统等。 + +### 5.ASP.NET Core具有以下优点: +- 跨平台,能够在Windows、macOS和Linux系统上开发、编译和运行。 +- 统一Web UI与Web API开发 +- 集成新式客户端框架和开发工作流 +- 基于环境配置以及云就绪配置 +- 内置依赖项注入 +- 轻型的高性能模块化HTTP请求管道 +- 能够在IIS、Nginx。Apache和Docker上进行托管或者在当前进程内自托管 +- 当目标框架为.NET Core时,支持并行应用版本控制 +- 简化新式Web开发工具 +- 开源和以社区为中心 + +### 6.ASP.NET Core主要特性 +(1)跨平台与“自我宿主” +(2)统一Web UI与Web API开发 +(3)内置依赖项注入 +(4)轻型的高性能模块化HTTP请求管道 +(5)基于环境配置以及云就绪配置 +(6)支持容器 + +### 7.创建一个API项目 +要创建一个ASP.NET Core Web API应用程序,可以使用Visual Studio,也可以使用ual Studio Core和JetBrains Rider等跨平台开发工具 +>>>>>>> 2c3bde2 (笔记) diff --git "a/\350\256\270\346\231\250/20240521-\345\210\233\345\273\272\350\247\243\345\206\263\346\226\271\346\241\210\345\222\214\351\241\271\347\233\256.md" "b/\350\256\270\346\231\250/20240521-\345\210\233\345\273\272\350\247\243\345\206\263\346\226\271\346\241\210\345\222\214\351\241\271\347\233\256.md" index 291eaad..5fa3b3a 100644 --- "a/\350\256\270\346\231\250/20240521-\345\210\233\345\273\272\350\247\243\345\206\263\346\226\271\346\241\210\345\222\214\351\241\271\347\233\256.md" +++ "b/\350\256\270\346\231\250/20240521-\345\210\233\345\273\272\350\247\243\345\206\263\346\226\271\346\241\210\345\222\214\351\241\271\347\233\256.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## 解决方案和项目之间的联系 1.编译或者打包解决方案的时候,会同时编译或打包其下所有的项目 2.如果运行解决方案的话,则会按照编排的(指定的启动项目),分别调整指定项目 @@ -13,3 +14,20 @@ dotnet sln add .\Admin2024.Api\ dotnet sln add .\Admin2024.Domain\ +======= +## 解决方案和项目之间的联系 +1.编译或者打包解决方案的时候,会同时编译或打包其下所有的项目 +2.如果运行解决方案的话,则会按照编排的(指定的启动项目),分别调整指定项目 + +## 创建一个解决方案包含两个项目 +dotnet new webapi -n Admin2024.Api + +dotnet new classlib -n Admin2024.Domain + +dotnet new sln -n Admin2024 + +dotnet sln add .\Admin2024.Api\ + +dotnet sln add .\Admin2024.Domain\ + +>>>>>>> 2c3bde2 (笔记) diff --git "a/\350\256\270\346\231\250/20240523-Startup\347\261\273.md" "b/\350\256\270\346\231\250/20240523-Startup\347\261\273.md" index 334c481..4463386 100644 --- "a/\350\256\270\346\231\250/20240523-Startup\347\261\273.md" +++ "b/\350\256\270\346\231\250/20240523-Startup\347\261\273.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## Startup类 IWebHostBuilder接口有很多扩展方法,其中有一个很重要的是UseStartup方法,它主要向应用程序提供用于配置启动的类,而指定的这个类应具有以下两个方法。 @@ -106,3 +107,113 @@ ASP.NET Core框架内部集成了自身的依赖注入容器。 +======= +## Startup类 + +IWebHostBuilder接口有很多扩展方法,其中有一个很重要的是UseStartup方法,它主要向应用程序提供用于配置启动的类,而指定的这个类应具有以下两个方法。 + +- ConfigureServices:用于向ASP.NET Core的依赖注入容器添加服务 +- Configure:用于添加中间件,配置请求管道 + +这两个方法都会在运行时被调用,且在应用程序的整个生命周期内,只执行一次。其中ConfigureServices方法是可选的,而Configure方法则是必选的。在程序启动时,它会执行ConfigureServices方法(如果有),将指定的服务放入应用程序的依赖注入容器中,然后再执行Configure方法,向请求管道中添加中间件。 + +## 今日作业 + +```C# +var builder = WebApplication.CreateBuilder(args); + +var app = builder.Build(); + +app.MapGet("/",async ctx => { + + await ctx.Response.WriteAsync("8888"); +}); + + +app.MapGet("/leaf",async ctx => { + + await ctx.Response.WriteAsync("9999"); +}); + +app.Run(); + + +``` + +1. 在最简单的形式下,转换为在单独的文件中写路径-抽离 + + + +2. 在最简形式下,转换为原来传统的控制器的模式-转换 + +Controllers里: + +``` +using Microsoft.AspNetCore.Mvc; + +namespace HHH.Controllers{ + +[ApiController] +[Route("[Controller]")] + +public class HomeController:Controller{ + public IActionResult Index(){ + return Ok("0123456"); + } +} + +} + +``` + + + +Program.cs里: + +``` + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.AddControllers(); + +var app = builder.Build(); +app.MapControllers(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); + +``` + +## ASP.NET Core中的依赖注入 + +ASP.NET Core框架内部集成了自身的依赖注入容器。 + +优点:功能强大、简单,容易使用且效率更高 + +在ASP.NET Core中,所有被放入依赖注入容器的类型或组件称为服务。容器中的服务有两种类型: + +- 框架服务 +- 应用服务 + + + + +>>>>>>> 2c3bde2 (笔记) diff --git "a/\350\256\270\346\231\250/20240524-\345\210\233\345\273\272\345\222\214\351\205\215\347\275\256 ASP.NET Core \345\272\224\347\224\250\347\250\213\345\272\217\347\232\204 Web \344\270\273\346\234\272\357\274\210Web Host\357\274\211.md" "b/\350\256\270\346\231\250/20240524-\345\210\233\345\273\272\345\222\214\351\205\215\347\275\256 ASP.NET Core \345\272\224\347\224\250\347\250\213\345\272\217\347\232\204 Web \344\270\273\346\234\272\357\274\210Web Host\357\274\211.md" index 759072a..8549b90 100644 --- "a/\350\256\270\346\231\250/20240524-\345\210\233\345\273\272\345\222\214\351\205\215\347\275\256 ASP.NET Core \345\272\224\347\224\250\347\250\213\345\272\217\347\232\204 Web \344\270\273\346\234\272\357\274\210Web Host\357\274\211.md" +++ "b/\350\256\270\346\231\250/20240524-\345\210\233\345\273\272\345\222\214\351\205\215\347\275\256 ASP.NET Core \345\272\224\347\224\250\347\250\213\345\272\217\347\232\204 Web \344\270\273\346\234\272\357\274\210Web Host\357\274\211.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## 创建和配置 ASP.NET Core 应用程序的 Web 主机(Web Host) ### Program.cs @@ -92,3 +93,99 @@ public void Configure(IApplicationBuilder app) */ ``` +======= +## 创建和配置 ASP.NET Core 应用程序的 Web 主机(Web Host) + +### Program.cs + +``` +// using Microsoft.Extensions.Hosting; 和 using Microsoft.AspNetCore.Hosting; 引入了应用程序所需的命名空间。 +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Hosting; + +// namespace Admin2024.Api 定义了应用程序的命名空间。 +namespace Admin2024.Api +{ + //定义了一个公共静态类 Program,它是应用程序的入口点。 +public static class Program +{ + + /* + public static void Main(string[] args) 定义了应用程序的入口点方法 Main,它接受一个字符串数组 args 作为参数。 + 在这个方法中,它调用了 CreateWebHostBuilder(args).Build().Run(),这将创建一个 Web 主机,并启动应用程序。 + + */ +public static void Main (string[] args) +{ + CreateWebHostBuilder(args).Build().Run(); +} + + +/* + +public static IHostBuilder CreateWebHostBuilder(string[] args) 定义了一个公共静态方法 CreateWebHostBuilder, +它接受一个字符串数组 args 作为参数,并返回一个 IHostBuilder 对象。 +在这个方法中,它调用了 Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(builder=>{builder.UseStartup();}), +这将创建一个默认的 Web 主机,并配置它使用 Startup 类。 + + +*/ +public static IHostBuilder CreateWebHostBuilder(string[] args) +{ + return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(builder=>{ + builder.UseStartup(); + }); +} + +} + + +} + +``` + + +### Startup.cs + +``` +namespace Admin2024.Api +{ +public class Startup +{ + /*ConfigureServices 方法用于配置应用程序所需的服务 + 在这个例子中,它调用了 services.AddControllers() + 这将添加一个控制器服务,用于处理 HTTP 请求*/ + public void ConfigureServices(IServiceCollection services) +{ + services.AddControllers(); +} + + + +/* +Configure 方法用于配置应用程序的管道,即请求和响应的处理流程。 +在这个例子中,它调用了 app.UseRouting(), +这将启用路由中间件,用于将请求路由到相应的控制器。 + +*/ + +public void Configure(IApplicationBuilder app) +{ + app.UseRouting(); + app.UseEndpoints(endPoints=>{ + endPoints.MapControllers(); + }); +} + + +} +} + +/* +调用了 app.UseEndpoints(endPoints=>{endPoints.MapControllers();}), +这将配置应用程序的终结点,即应用程序的入口和出口。 +在这个例子中,它调用了 endPoints.MapControllers(),这将将请求路由到相应的控制器。 +*/ + +``` +>>>>>>> 2c3bde2 (笔记) diff --git "a/\350\256\270\346\231\250/20240527-\347\220\206\350\247\243MVC\346\250\241\345\274\217\345\222\214\350\267\257\347\224\261.md" "b/\350\256\270\346\231\250/20240527-\347\220\206\350\247\243MVC\346\250\241\345\274\217\345\222\214\350\267\257\347\224\261.md" index 8435c94..d66fed9 100644 --- "a/\350\256\270\346\231\250/20240527-\347\220\206\350\247\243MVC\346\250\241\345\274\217\345\222\214\350\267\257\347\224\261.md" +++ "b/\350\256\270\346\231\250/20240527-\347\220\206\350\247\243MVC\346\250\241\345\274\217\345\222\214\350\267\257\347\224\261.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## 理解MVC模式 1.概念: @@ -50,3 +51,57 @@ public IActionResult Get(string id) 另外,还有一下两个特性用于指明参数是否必须使用绑定: - BindRequiredAttribute:如果没有值绑定到此参数,或绑定不成功,这个特性将添加一个ModelState错误。 - BindNeverAttribute:在进行模型绑定时,忽略此参数。 +======= +## 理解MVC模式 + +1.概念: + +MVC是模型(Model)、视图(View)、控制器(Controller)的缩写,它是Web应用程序中一种常用的架构模式。 + +## 路由 + +对于Web应用程序,路由是一个非常重要且基本的功能,它的主要功能是根据预先配置的路由信息对客户端传来的请求进行路由映射,映射完成后,再将请求传给对应的路由处理器信息。 + +具体来说,在ASP.NET Core MVC 中,路由负责从请求的URL中获取信息,并根据这些信息来定位或映射到对应的Controller与Action。 + +在开发Web API应用程序时,使用的HTTP特性 + +|HTTP特性|HTTP方法|URL示例| +| --- | --- | --- | +|[HttpGet] |Get |api/blogs(获取列表) api/blogs/1(获取指定ID)| +|[HttpPost]|POST|api/blogs| +|[HttpPut] |PUT|api/blogs/1| +|[HttpPatch]|PATCH|api/blogs/1| +|[HttpDelete]|Delete|api/blogs/1| + +由于每一个特性对应一个HTTP方法,因此如果要获取一个资源,可以这样使用: + +``` +[Router("api/[controller]")] +public class BlogsController :Controller +{ +[HttpGet("{id}")] +public IActionResult Get(string id) +{ + ... +} + +} + +``` + +## 模型绑定 +使用如下特性能够为Action的参数显示指定不同的绑定资源: + +- [FromHeader]特性:从HTTP请求的Header中获取参数的值。 +- [FromQuery]特性:从查询字符串中获取参数的值。 +- [FromService]特性:从依赖注入容器中获取参数的值。 +- [FromRouter]特性:从路由中获取参数的值。 +- [FromFrom]特性:从表单中获取参数的值。 +- [FromBody]特性:从HTTP请求的消息正文中获取参数的值。 + + +另外,还有一下两个特性用于指明参数是否必须使用绑定: +- BindRequiredAttribute:如果没有值绑定到此参数,或绑定不成功,这个特性将添加一个ModelState错误。 +- BindNeverAttribute:在进行模型绑定时,忽略此参数。 +>>>>>>> 2c3bde2 (笔记) diff --git "a/\350\256\270\346\231\250/20240528-\350\277\207\346\273\244\345\231\250\345\222\214\346\227\245\345\277\227.md" "b/\350\256\270\346\231\250/20240528-\350\277\207\346\273\244\345\231\250\345\222\214\346\227\245\345\277\227.md" index 2614319..d5757be 100644 --- "a/\350\256\270\346\231\250/20240528-\350\277\207\346\273\244\345\231\250\345\222\214\346\227\245\345\277\227.md" +++ "b/\350\256\270\346\231\250/20240528-\350\277\207\346\273\244\345\231\250\345\222\214\346\227\245\345\277\227.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## 一、路由 1.在控制器上写上两个特性 @@ -80,3 +81,87 @@ Log方法的第一个参数指明了这条信息的级别,日志级别即其 +======= +## 一、路由 + +1.在控制器上写上两个特性 + +- + [ApiController] +- + [Route("/api/...")] + +2.如果不符合restfull风格的路由的话,在action上单独写路由 + +- +[HttpGet("/api/...")] + +## 二、关于匹配到函数的处理 +(1)入参:函数的参数,模型绑定 +(2)返回值:返回的响应, +1.状态码 +2.带对象的状态码 +3.重定向 +4.内容{ + code:1000, + data:[], + msg:'请求成功' +} + +## 过滤器 + +ASP.NET Core MVC提供了以下5种类型的过滤器 +- Authorization:最先执行,用于判断用户是否授权 +- Resource过滤器 +- Action过滤器 +- Exception过滤器:用于捕获异常 +- Result过滤器 + + + +## 日志 + +日志包括两种类型: +- 系统日志:系统日志是系统在运行时向外输出的记录信息 +- 用户记录日志:用户记录日志是由开发人员在程序中适当的位置调用与日志功能相关的API输出的日志 + +一般情况下,记录日志时也可以指定其重要级别,如调试、信息、警告和错误等。 + +ASP.NET Core框架内部集成了日志功能,它主要由以下一些重要的接口组成 +- Ilogger:包括实际执行记录日志操作的方法 +- IloggerProvider:用于创建ILogger对象 +- IloggerFactory:通过IloggerProvider对象创建ILogger对象 + +1.ILogger接口 + +要记录日志,需要使用ILogger接口,它的定义如下 + +``` +public interface ILogger +{ +IDisposable BeginScope(TState state); +bool IsEnabled(LogLevel logLevel); +void Log (LogLevel logLevel,EventId eventId,TAtate state,Exception exception,Funcformatter); +} + +``` + +其中,Log方法用于记录日志,它包括5个参数,使用方法如下 + +``` +logger.Log(LogLevel.Information,0,typeof(object),null,(type,exception)=>"Hello World"); +``` + + +Log方法的第一个参数指明了这条信息的级别,日志级别即其重要程度。ASP.NET Core日志系统定义了6个级别,具体如下: +- Trace:级别最低,通常仅用于开发阶段调试问题,这些信息可能包含敏感的应用程序数据,因此不应该用于生产环境,默认情况应禁用,即不输出。 +- Debug:用于记录调试信息,这种类型的日志有助于开发人员调试应用程序 +- Information:用于记录应用程序的执行流程信息,这些信息具有一定意义 +- Warning:用于记录应用程序出现的轻微错误或其他不会导致程序停止的警告信息 +- Error:用于记录错误信息,这一类的错误将影响程序正常执行 +- Critical:严重级别最高,用于记录引起应用程序崩溃、灾难性故障等信息,如数据丢失、磁盘空间不够等 + + + + + + + +>>>>>>> 2c3bde2 (笔记) diff --git "a/\350\256\270\346\231\250/20240530-\345\206\205\345\255\230\345\236\213\346\225\260\346\215\256\345\272\223.md" "b/\350\256\270\346\231\250/20240530-\345\206\205\345\255\230\345\236\213\346\225\260\346\215\256\345\272\223.md" index 70c75f2..d40c4d5 100644 --- "a/\350\256\270\346\231\250/20240530-\345\206\205\345\255\230\345\236\213\346\225\260\346\215\256\345\272\223.md" +++ "b/\350\256\270\346\231\250/20240530-\345\206\205\345\255\230\345\236\213\346\225\260\346\215\256\345\272\223.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## 内存型数据库 - 创建一个Db对象 ```csharp @@ -23,4 +24,31 @@ - `Db`指的是内存型数据库,自己创建的数据库 - `Domain`指的是实体类对象,用来放字段 - `interfaces`指的是接口类对象(`I`实例名`Repository`结尾) +======= +## 内存型数据库 +- 创建一个Db对象 +```csharp + public static BookDtoreDb Instance{get;set;}=new BookStoreDb(); + public Icollection<实例对象1> 名1 {get;set;}=new List<实例对象1>(); + public Icollection<实例对象2> 名2 {get;set;}=new List<实例对象2>(); + //初始化数据 + public BookStoreDb() + { + 名1.Add(new 实例名{ + 字段1=值1, + 字段2=值2 + }) + } +``` + +### 集合的操作 +> 较多使用:ICollection、IList、IComparer + +![alt text](./imgs/i..Repository.png) + +### 各类文件夹的代指 +- `Db`指的是内存型数据库,自己创建的数据库 +- `Domain`指的是实体类对象,用来放字段 +- `interfaces`指的是接口类对象(`I`实例名`Repository`结尾) +>>>>>>> 2c3bde2 (笔记) - `Services`是接口的实现类(实例名`Repository`结尾) \ No newline at end of file diff --git "a/\350\256\270\346\231\250/20240531-\346\216\245\345\217\243.md" "b/\350\256\270\346\231\250/20240531-\346\216\245\345\217\243.md" index 053ff50..7d59eff 100644 --- "a/\350\256\270\346\231\250/20240531-\346\216\245\345\217\243.md" +++ "b/\350\256\270\346\231\250/20240531-\346\216\245\345\217\243.md" @@ -1,3 +1,4 @@ +<<<<<<< HEAD ## 接口 - I实例名Repository ```csharp @@ -51,4 +52,59 @@ //新加 services.AddScoped(); } +======= +## 接口 +- I实例名Repository + ```csharp + //通过Id获取所有作者的实现 + 实例对象? GetAuthorById(Guid guid); + + //获取所有作者的方法 + //函数三要素(函数名,形参,返回值) + ICollection<实例对象> GetAllAuthors(); + + ``` +- 实例名Repository + ```csharp + public class 实例名Repository:I实例名Repository + { + public ICollection<实例名> GetAllAuthors() + { + //从持久化数据库中获取 + return 名Db.Instance.实例名.ToList(); + //return [.. 名Db.Instance.实例名]; + } + public 实例名? GetAuthorById(Guid guid) + { + return 名Db.Instance.实例名.SingleOrDefault(item=>item.Id==guid); + } + } + ``` +- 控制器中 + ```csharp + private readonly I实例名Repository _实例名Repository; + public 实例名Controller(I实例名Repository 实例名Repository) + { + _实例名Repository=实例名Repository; + } + //获取get的函数中 + [HttpGet("{id?}")] + public IActionResult Get(int id) + { + if(id.ToString==""){ + return Ok(_实例名Repository.GetAllAuthors()); + }else{ + return Ok(_实例名Repository.GetAuthorById(id)); + } + } + ``` +- Startup + ```csharp + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); + //新加 + services.AddScoped(); + } +>>>>>>> 2c3bde2 (笔记) ``` \ No newline at end of file diff --git "a/\350\256\270\346\231\250/20240603-\351\241\271\347\233\256\345\256\236\347\216\260\351\203\250\345\210\206.md" "b/\350\256\270\346\231\250/20240603-\351\241\271\347\233\256\345\256\236\347\216\260\351\203\250\345\210\206.md" new file mode 100644 index 0000000..33b84c7 --- /dev/null +++ "b/\350\256\270\346\231\250/20240603-\351\241\271\347\233\256\345\256\236\347\216\260\351\203\250\345\210\206.md" @@ -0,0 +1,73 @@ +### Controllers BooksController.cs + +``` +using BookStore.Api.Db; +using BookStore.Api.Interface; +using Microsoft.AspNetCore.Mvc; + +namespace BookStore.Api.Controller; + +[ApiController] +[Route("api/authors/{authorId}/[controller]/")] +public class BooksController : ControllerBase +{ + + private readonly IBookRepository _bookRepository; + + public BooksController(IBookRepository bookRepository) + { + _bookRepository = bookRepository; + } + + [HttpGet("{bookId?}")] + public IActionResult Get(Guid authorId, Guid bookId) + { + if (bookId.ToString() == "00000000-0000-0000-0000-000000000000") + { + var list = _bookRepository.GetAllBooks(authorId); + return Ok(list); + } + + var result = _bookRepository.GetBookById(authorId, bookId); + + return Ok(result); + } + + [HttpPost] + public IActionResult Post(Guid authorId) + { + return Ok(); + } + + [HttpPut("{id}")] + public IActionResult Put(Guid authorId, Guid id) + { + return Ok(id); + } + + [HttpDelete("{id}")] + public IActionResult Del(Guid authorId, Guid id) + { + return Ok(id); + } +} + +``` + + +### Domain Books.cs + +``` +namespace BookStore.Api.Domain; + +public class Books +{ + public Guid Id { get; set; } + public string BookName { get; set; } = null!; + public string? Publisher { get; set; } + public int Price { get; set; } + public Guid AuthorId { get; set; } +} + +``` + diff --git "a/\350\256\270\346\231\250/20240604-\345\270\270\350\247\201\351\233\206\345\220\210\346\216\245\345\217\243.md" "b/\350\256\270\346\231\250/20240604-\345\270\270\350\247\201\351\233\206\345\220\210\346\216\245\345\217\243.md" new file mode 100644 index 0000000..a5e06b9 --- /dev/null +++ "b/\350\256\270\346\231\250/20240604-\345\270\270\350\247\201\351\233\206\345\220\210\346\216\245\345\217\243.md" @@ -0,0 +1,24 @@ +## 常见集合接口 + +![20240604105805](https://oss.9ihub.com/test/20240604105805.png) + + + +@startuml +interface IEnumerable { + + GetEnumerator(): IEnumerator +} +interface IEnumerator { + + Current: object + + MoveNext(): bool + + Reset() +} +interface ICollection +interface IList +interface IDictionary + +IEnumerable --> IEnumerator +IEnumerable <|.. ICollection +ICollection <|.. IList +ICollection <|.. IDictionary +@enduml \ No newline at end of file diff --git "a/\350\256\270\346\231\250/20240606-\345\256\214\346\210\220\345\233\276\344\271\246\347\232\204\346\226\260\345\242\236\343\200\201\344\277\256\346\224\271\346\216\245\345\217\243.md" "b/\350\256\270\346\231\250/20240606-\345\256\214\346\210\220\345\233\276\344\271\246\347\232\204\346\226\260\345\242\236\343\200\201\344\277\256\346\224\271\346\216\245\345\217\243.md" new file mode 100644 index 0000000..27addc1 --- /dev/null +++ "b/\350\256\270\346\231\250/20240606-\345\256\214\346\210\220\345\233\276\344\271\246\347\232\204\346\226\260\345\242\236\343\200\201\344\277\256\346\224\271\346\216\245\345\217\243.md" @@ -0,0 +1,115 @@ +### Services BookRepository.cs + +``` +using BookStore.Api.Db; +using BookStore.Api.Domain; +using BookStore.Api.Dto; +using BookStore.Api.Interface; + +namespace BookStore.Api.Services; + +public class BookRepository : IBookRepository +{ + public BookDto? Delete(Guid authorId, Guid BookId) + { + return new BookDto(); + } + + public ICollection GetAllBooks(Guid authorId) + { + /* + 较好的做法,是确认对应authorId下有没有对应的作者, + 并且作者的状态是否是正确的(没有被删除,没有被禁用,没有被限制功能) + + 如果业务不允许,则返回作者状态不正确的结果 + */ + var list = BookStoreDb.Instance.Books.Where(item => item.AuthorId == authorId) + .Select(item => new BookDto { Id = item.Id, AuthorId = item.AuthorId, BookName = item.BookName }).ToList(); + return list; + } + + public BookDto? GetBookById(Guid authorId, Guid bookId) + { + var author = BookStoreDb.Instance.Authors.FirstOrDefault(item => item.Id == authorId); + if (author == null) + { + return null; + } + var book = BookStoreDb.Instance.Books.FirstOrDefault(item => item.AuthorId == authorId && item.Id == bookId); + + if (book == null) + { + return null; + } + return new BookDto { Id = book.Id, BookName = book.BookName, AuthorId = book.AuthorId }; + } + + public BookDto? Insert(Guid authorId, BookCreateDto bookCreateDto) + { + /* + 1.确认传入的authorId存在对应的记录 + 如果存在,继续后面的流程;否则返回null + 2.将输入的数据进行整理转换,插入到数据中 + 1. 将BookCreateDto类型的数据转换成Books类型的数据 + 2. 将转换到books数据插入数据库表 + + 为了简单,目前从未对传入数据进行任何验证,原因就是为了让整个应用尽量简单,后续一定要进行数据验证 + 1. 简单验证 数据类型,是否为空,字符长度,是否一定格式等等 + 2. 复杂验证或者叫业务验证 + + */ + + var author = BookStoreDb.Instance.Authors.FirstOrDefault(item => item.Id == authorId); + if (author == null) + { + return null; + } + var tmp = new Books + { + Id = Guid.NewGuid(), + BookName = bookCreateDto.BookName, + Publisher = bookCreateDto.Publisher, + Price = bookCreateDto.Price, + AuthorId = authorId + }; + + BookStoreDb.Instance.Books.Add(tmp); + + var result = new BookDto { Id = tmp.Id, BookName = tmp.BookName, AuthorId = tmp.AuthorId, Author = author }; + + return result; + } + + public BookDto? Update(Guid authorId, Guid BookId, BookUpdateDto bookUpdateDto) + { + /* + 1. 要修改的指定的作者是不是在,如果不在则返回null,如果在则继续 + 2. 要修改的指定的图书book是不是存在,如果不存在则返回null,如果存在则继续 + 3. 完成book数据的更改和保存 + 将传入的bookUpdateDto数据赋值给book,就可以了 + + */ + + var author = BookStoreDb.Instance.Authors.FirstOrDefault(item => item.Id == authorId); + if (author == null) + { + return null; + } + + var book = BookStoreDb.Instance.Books.FirstOrDefault(item => item.Id == BookId); + if (book == null) + { + return null; + } + + book.BookName = bookUpdateDto.BookName; + book.Publisher = bookUpdateDto.Publisher; + book.Price = bookUpdateDto.Price; + book.BookName = bookUpdateDto.BookName; + + var result = new BookDto { Id = book.Id, BookName = book.BookName, AuthorId = book.AuthorId }; + return result; + } +} + +``` \ No newline at end of file diff --git "a/\350\256\270\346\231\250/20240607-\345\274\225\345\205\245EFCore.md" "b/\350\256\270\346\231\250/20240607-\345\274\225\345\205\245EFCore.md" new file mode 100644 index 0000000..44ea2ac --- /dev/null +++ "b/\350\256\270\346\231\250/20240607-\345\274\225\345\205\245EFCore.md" @@ -0,0 +1,213 @@ +## 引入EFCore + +RepositoryBase.cs + +``` +namespace BookStore.Api.Interface; + +/// +/// 基础仓储接口,定义通用的CRUD功能 +/// +public interface IRepositoryBase +{ + /* + 通过id获取指定模型(对应数据库中的表,模型中的公共属性对应数据表的字段或者叫列) + 获取所有的模型 + + 获取所有实体 + + 新增插入 + + 删除 + + + 更新 + + */ + + T GetById(Guid id); + + List GetAll(); + + T Insert(T entity); + T Update(T entity); + T Delete(T entity); + T Delete(Guid id); +} + +``` + + + +Startup.cs + +``` +using BookStore.Api.Db; +using BookStore.Api.Interface; +using BookStore.Api.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace BookStore.Api; + +public class Startup +{ + private readonly IConfiguration _configuration; + + public Startup(IConfiguration configuration) + { + _configuration = configuration; + } + public void Configure(IApplicationBuilder app, IHostEnvironment env) + { + // 如果是开发环境,则引入Swagger +@@ -16,7 +24,7 @@ public class Startup + } + // 路由中间件 + app.UseRouting(); + + + // 配置路由端点匹配控制器 + app.UseEndpoints(endPoints => + { +@@ -36,5 +44,11 @@ public class Startup + // 将仓储服务注册到容器 + services.AddScoped(); + services.AddScoped(); + + // 注册数据库上下文到容器 + services.AddDbContext( + option => + option.UseSqlServer(_configuration.GetConnectionString("Mssql")) + ); + } +} + + +``` + + +BookStoreDbContexModelSnapshot.cs + +``` +using System; +using BookStore.Api.Db; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BookStore.Api.Migrations +{ + [DbContext(typeof(BookStoreDbContext))] + partial class BookStoreDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BookStore.Api.Domain.Authors", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Birthday") + .HasColumnType("datetime2"); + + b.Property("Gender") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("BookStore.Api.Domain.Books", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("BookName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("Publisher") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("BookStore.Api.Domain.Users", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} + + +``` + + + + +BookStoreDbContext.cs + +``` +using BookStore.Api.Domain; +using Microsoft.EntityFrameworkCore; + +namespace BookStore.Api.Db; + +public class BookStoreDbContext : DbContext +{ + public BookStoreDbContext(DbContextOptions options) : base(options) + { + + } + + + public DbSet Authors { get; set; } + public DbSet Books { get; set; } + public DbSet Users { get; set; } + +} + + +``` \ No newline at end of file -- Gitee