From cb7fcbd82c692e2d2efa1a1f5152383d8e1b2bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=81=A9=E7=94=9F?= <2156286470@qq.com> Date: Sun, 14 Jun 2026 23:36:44 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...50\256\260-\345\256\211\350\243\205SDK.md" | 37 +++++++ ...33\345\273\272\351\241\271\347\233\256.md" | 36 +++++++ ...\254\224\350\256\260-nuget\345\214\205.md" | 35 +++++++ "20260605\347\254\224\350\256\260-CRUD.md" | 90 +++++++++++++++++ ...74\350\210\252\345\261\236\346\200\247.md" | 69 +++++++++++++ "\351\273\204\346\235\245\350\215\243/.keep" | 0 .../20260601-\345\256\211\350\243\205SDK.md" | 10 -- ...33\345\273\272\351\241\271\347\233\256.md" | 21 ---- .../20260604-nuget\345\214\205.md" | 15 --- .../20260605-CRUD.md" | 21 ---- ...26\351\224\256\345\205\263\347\263\273.md" | 98 ------------------- 11 files changed, 267 insertions(+), 165 deletions(-) create mode 100644 "20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" create mode 100644 "20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" create mode 100644 "20260604\347\254\224\350\256\260-nuget\345\214\205.md" create mode 100644 "20260605\347\254\224\350\256\260-CRUD.md" create mode 100644 "20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" delete mode 100644 "\351\273\204\346\235\245\350\215\243/.keep" delete mode 100644 "\351\273\204\346\235\245\350\215\243/20260601-\345\256\211\350\243\205SDK.md" delete mode 100644 "\351\273\204\346\235\245\350\215\243/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" delete mode 100644 "\351\273\204\346\235\245\350\215\243/20260604-nuget\345\214\205.md" delete mode 100644 "\351\273\204\346\235\245\350\215\243/20260605-CRUD.md" delete mode 100644 "\351\273\204\346\235\245\350\215\243/20260608-webapi\344\270\255\347\232\204\344\270\273\345\244\226\351\224\256\345\205\263\347\263\273.md" diff --git "a/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" "b/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" new file mode 100644 index 0000000..f7d647a --- /dev/null +++ "b/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" @@ -0,0 +1,37 @@ +# 2026-06-01 笔记 — 安装 SDK + +## 目标 +安装并验证用于开发 Web API 的 .NET SDK 与相关工具。 + +## 前提 +- Windows 操作系统 +- 管理员权限(安装时可能需要) + +## 安装步骤 +1. 访问 .NET 官方下载页:https://dotnet.microsoft.com/download +2. 选择对应的 SDK 版本(推荐 LTS 版本),点击下载并运行安装程序。 +3. 安装完成后打开命令行(PowerShell 或 CMD),运行: + + ```powershell + dotnet --info + ``` + + - 确认已显示 SDK 和运行时版本。 + +4. 可选:安装 Visual Studio Code(轻量)并添加扩展: + - C# (由 Microsoft) + - NuGet Package Manager + - REST Client / Thunder Client(测试 API) + +5. 配置环境变量(通常安装程序会自动配置)。如未生效,重启终端或手动将 `C:\Program Files\dotnet` 加入 `PATH`。 + +## 验证 +- `dotnet --version` 返回版本号 +- 使用 `dotnet new webapi -n TestApi` 创建测试项目并运行 `dotnet run`,访问 `https://localhost:5001` 验证启动。 + +## 常见问题 +- 安装失败:检查是否有旧版本冲突、管理员权限或杀毒软件阻止。 +- 找不到命令:确认 `PATH` 包含 dotnet 安装目录并重启终端。 + +--- +*结束* \ No newline at end of file diff --git "a/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" "b/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" new file mode 100644 index 0000000..89a2ec0 --- /dev/null +++ "b/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" @@ -0,0 +1,36 @@ +# 2026-06-03 笔记 — 创建项目 + +## 目标 +使用 .NET CLI 创建 Web API 项目,并了解项目结构与常用命令。 + +## 创建项目 +1. 打开终端并进入工作目录。 +2. 运行命令: + + ```powershell + dotnet new webapi -n Grade24Class2Api + cd Grade24Class2Api + ``` + +3. 项目结构说明: + - `Program.cs`:应用入口,配置主机与中间件。 + - `appsettings.json`:配置文件。 + - `Controllers/WeatherForecastController.cs`:示例控制器。 + - `Properties/launchSettings.json`:调试配置(端口、环境变量)。 + +## 常用命令 +- 恢复依赖:`dotnet restore` +- 构建:`dotnet build` +- 运行:`dotnet run` +- 发布:`dotnet publish -c Release -o ./publish` +- 添加包:`dotnet add package ` + +## 运行与测试 +- 运行 `dotnet run`,打开浏览器访问 `https://localhost:5001/swagger/index.html` 查看 Swagger 文档。 + +## 小贴士 +- 使用 `--no-https` 或在 `launchSettings.json` 中调整端口用于本地测试。 +- 可将项目初始化为 git 仓库:`git init`,并添加 `.gitignore`。 + +--- +*结束* \ No newline at end of file diff --git "a/20260604\347\254\224\350\256\260-nuget\345\214\205.md" "b/20260604\347\254\224\350\256\260-nuget\345\214\205.md" new file mode 100644 index 0000000..edf7380 --- /dev/null +++ "b/20260604\347\254\224\350\256\260-nuget\345\214\205.md" @@ -0,0 +1,35 @@ +# 2026-06-04 笔记 — NuGet 包 + +## 目标 +学习如何管理 NuGet 包、搜索、安装和更新依赖。 + +## 常用命令 +- 搜索包:`dotnet search `(部分 SDK 版本支持) +- 添加包:`dotnet add package --version x.y.z` +- 更新包:`dotnet add package --version ` 或使用 `dotnet tool` 的方式 +- 列出已安装包:`dotnet list package` + +## NuGet 源 +- 默认源为 nuget.org。 +- 添加私人源: + + ```powershell + dotnet nuget add source "https://myfeed.example.com/nuget" -n MyFeed + ``` + +- 删除源:`dotnet nuget remove source MyFeed` + +## Visual Studio Code 支持 +- 安装 `NuGet Package Manager` 扩展以在编辑器中管理包。 + +## 常见包示例 +- `Microsoft.EntityFrameworkCore` 与数据库提供器(SqlServer/PostgreSQL) +- `Swashbuckle.AspNetCore`(Swagger) +- `AutoMapper`(对象映射) + +## 注意事项 +- 指定版本以避免意外升级破坏兼容性。 +- 使用 `PackageReference` 在项目文件中声明依赖(CLI 默认行为)。 + +--- +*结束* \ No newline at end of file diff --git "a/20260605\347\254\224\350\256\260-CRUD.md" "b/20260605\347\254\224\350\256\260-CRUD.md" new file mode 100644 index 0000000..8ef9983 --- /dev/null +++ "b/20260605\347\254\224\350\256\260-CRUD.md" @@ -0,0 +1,90 @@ +# 2026-06-05 笔记 — CRUD 操作 + +## 目标 +实现基本的增删改查(Create/Read/Update/Delete)API,使用 Entity Framework Core 持久化数据。 + +## 安装 EF Core +- 安装主包与数据库提供器: + + ```powershell + dotnet add package Microsoft.EntityFrameworkCore + dotnet add package Microsoft.EntityFrameworkCore.SqlServer + dotnet add package Microsoft.EntityFrameworkCore.Tools + ``` + +## 创建模型与 DbContext +- 示例模型: + + ```csharp + public class Student + { + public int Id { get; set; } + public string Name { get; set; } + public int Age { get; set; } + } + ``` + +- DbContext: + + ```csharp + public class SchoolContext : DbContext + { + public SchoolContext(DbContextOptions options) : base(options) { } + public DbSet Students { get; set; } + } + ``` + +- 在 `Program.cs` 中注册: + + ```csharp + builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); + ``` + +## 迁移与数据库更新 +- 添加迁移:`dotnet ef migrations add InitialCreate` +- 更新数据库:`dotnet ef database update` + +## 控制器示例(StudentsController) +- 创建、读取、更新、删除示例方法: + + ```csharp + [HttpGet] + public async Task>> Get() => await _context.Students.ToListAsync(); + + [HttpGet("{id}")] + public async Task> Get(int id) => await _context.Students.FindAsync(id); + + [HttpPost] + public async Task Create(Student student) + { + _context.Students.Add(student); + await _context.SaveChangesAsync(); + return CreatedAtAction(nameof(Get), new { id = student.Id }, student); + } + + [HttpPut("{id}")] + public async Task Update(int id, Student student) + { + if (id != student.Id) return BadRequest(); + _context.Entry(student).State = EntityState.Modified; + await _context.SaveChangesAsync(); + return NoContent(); + } + + [HttpDelete("{id}")] + public async Task Delete(int id) + { + var student = await _context.Students.FindAsync(id); + if (student == null) return NotFound(); + _context.Students.Remove(student); + await _context.SaveChangesAsync(); + return NoContent(); + } + ``` + +## 测试 +- 使用 Postman / Thunder Client 测试各个端点。 + +--- +*结束* \ No newline at end of file diff --git "a/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" "b/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" new file mode 100644 index 0000000..8543f5b --- /dev/null +++ "b/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" @@ -0,0 +1,69 @@ +# 2026-06-08 笔记 — 导航属性 + +## 目标 +理解 Entity Framework Core 中的导航属性(Navigation Properties)及其用法,包含一对多、多对多与级联删除行为。 + +## 模型示例 +- `Student` 与 `Course` 的多对多关系(EF Core 5+ 可直接支持): + + ```csharp + public class Student + { + public int Id { get; set; } + public string Name { get; set; } + public ICollection Courses { get; set; } + } + + public class Course + { + public int Id { get; set; } + public string Title { get; set; } + public ICollection Students { get; set; } + } + ``` + +## 配置关系 +- 使用 Fluent API 在 `OnModelCreating` 中配置: + + ```csharp + modelBuilder.Entity() + .HasMany(s => s.Courses) + .WithMany(c => c.Students) + .UsingEntity(j => j.ToTable("Enrollments")); + ``` + +## 一对多示例 +- `Teacher` 和 `Course`: + + ```csharp + public class Teacher { public int Id { get; set; } public string Name { get; set; } public ICollection Courses { get; set; } } + public class Course { public int Id { get; set; } public string Title { get; set; } public int TeacherId { get; set; } public Teacher Teacher { get; set; } } + ``` + +- 配置: + + ```csharp + modelBuilder.Entity() + .HasMany(t => t.Courses) + .WithOne(c => c.Teacher) + .HasForeignKey(c => c.TeacherId); + ``` + +## 级联删除 +- 默认行为:当主实体被删除时,相关依赖实体会根据 FK 配置执行级联删除或设置为空。 +- 显式配置:`OnDelete(DeleteBehavior.Cascade)` 或 `OnDelete(DeleteBehavior.SetNull)`。 + +## 加载导航属性 +- 立即加载(Eager Loading):使用 `Include()`: + `var students = context.Students.Include(s => s.Courses).ToList();` +- 延迟加载(Lazy Loading):需要安装 `Microsoft.EntityFrameworkCore.Proxies` 并启用代理: + `builder.Services.AddDbContext(options => options.UseLazyLoadingProxies().UseSqlServer(...));` +- 显式加载(Explicit Loading): + `context.Entry(student).Collection(s => s.Courses).Load();` + +## 注意事项 +- 控制查询性能,避免 N+1 问题。 +- 在序列化到 JSON 时注意循环引用(使用 DTO 或配置 `ReferenceHandler.IgnoreCycles`)。 + +--- +*结束* \ No newline at end of file diff --git "a/\351\273\204\346\235\245\350\215\243/.keep" "b/\351\273\204\346\235\245\350\215\243/.keep" deleted file mode 100644 index e69de29..0000000 diff --git "a/\351\273\204\346\235\245\350\215\243/20260601-\345\256\211\350\243\205SDK.md" "b/\351\273\204\346\235\245\350\215\243/20260601-\345\256\211\350\243\205SDK.md" deleted file mode 100644 index 7eb7612..0000000 --- "a/\351\273\204\346\235\245\350\215\243/20260601-\345\256\211\350\243\205SDK.md" +++ /dev/null @@ -1,10 +0,0 @@ -## 笔记 - -安装SDK - -1.访问 https://dotnet.microsoft.com/download/dotnet/8.0 -2.下载 .NET 8.0 SDK(不要下错成 Runtime) -3.双击安装包,按提示完成 - - -## 练习 \ No newline at end of file diff --git "a/\351\273\204\346\235\245\350\215\243/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" "b/\351\273\204\346\235\245\350\215\243/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" deleted file mode 100644 index efa72d7..0000000 --- "a/\351\273\204\346\235\245\350\215\243/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" +++ /dev/null @@ -1,21 +0,0 @@ -## 笔记 - -创建项目 - -在终端(PowerShell / bash)里: - - 切到你想放代码的目录:mkdir MyShopApi && cd MyShopApi - - 创建 Web API 项目:dotnet new webapi -n MyShopApi --use-controllers - - 进入项目目录:cd MyShopApi - - - webapi:项目模板名 - - -n MyShopApi:项目名(生成的目录名、命名空间) - - --use-controllers:用 Controller-based 风格(vs Minimal API) - - -## 练习 \ No newline at end of file diff --git "a/\351\273\204\346\235\245\350\215\243/20260604-nuget\345\214\205.md" "b/\351\273\204\346\235\245\350\215\243/20260604-nuget\345\214\205.md" deleted file mode 100644 index 73476e2..0000000 --- "a/\351\273\204\346\235\245\350\215\243/20260604-nuget\345\214\205.md" +++ /dev/null @@ -1,15 +0,0 @@ -## 笔记 - -装 NuGet 包与 dotnet-ef 工具 - -安装NuGet 包 - - dotnet add package Microsoft.EntityFrameworkCore.Sqlite -v 8—— SQLite 数据库 provider - dotnet add package Microsoft.EntityFrameworkCore.Design-v 8—— 迁移命令依赖(dotnet ef) - -安装dotnet-ef 工具 - - dotnet tool install --global dotnet-ef - 验证:dotnet ef --version - -## 练习 \ No newline at end of file diff --git "a/\351\273\204\346\235\245\350\215\243/20260605-CRUD.md" "b/\351\273\204\346\235\245\350\215\243/20260605-CRUD.md" deleted file mode 100644 index 1d8563e..0000000 --- "a/\351\273\204\346\235\245\350\215\243/20260605-CRUD.md" +++ /dev/null @@ -1,21 +0,0 @@ -## 笔记 - - -CRUD改造 - -通过构造函数注入拿到AppDbContext实例: - - public class CategoriesController : ControllerBase - { - private readonly AppDbContext _db; - - public CategoriesController(AppDbContext db) - { - _db = db; - } - - // ... - } - - -## 练习 \ No newline at end of file diff --git "a/\351\273\204\346\235\245\350\215\243/20260608-webapi\344\270\255\347\232\204\344\270\273\345\244\226\351\224\256\345\205\263\347\263\273.md" "b/\351\273\204\346\235\245\350\215\243/20260608-webapi\344\270\255\347\232\204\344\270\273\345\244\226\351\224\256\345\205\263\347\263\273.md" deleted file mode 100644 index 8f5c82d..0000000 --- "a/\351\273\204\346\235\245\350\215\243/20260608-webapi\344\270\255\347\232\204\344\270\273\345\244\226\351\224\256\345\205\263\347\263\273.md" +++ /dev/null @@ -1,98 +0,0 @@ -# 笔记 - ---- - -## 🧩 核心概念 - -| 概念 | 说明 | -| -------------- | --------------------------------------------------- | -| **一对多关系** | 一个实体(Category)对应多个另一个实体(Product) | -| **导航属性** | 实体间通过属性表达关系,而不是靠手动写 JOIN | -| **外键** | “多”端存储“一”端的主键值(如 `Product.CategoryId`) | - ---- - -## 🧱 实体配置模板 - -```csharp -// “一”端:Category -public ICollection Products { get; set; } - -// “多”端:Product -public int CategoryId { get; set; } -public Category? Category { get; set; } -``` - -**EF Core 约定识别规则**: -- 集合类型 → “一”端 -- 引用类型 → “多”端 -- `<类名>Id` → 外键 - ---- - -## ⚙️ `OnModelCreating` 显式配置(推荐) - -```csharp -modelBuilder.Entity() - .HasOne(p => p.Category) - .WithMany(c => c.Products) - .HasForeignKey(p => p.CategoryId) - .OnDelete(DeleteBehavior.Restrict); -``` - -### 🔁 方向解释 -- `HasOne` → Product 有一个 Category -- `WithMany` → Category 有多个 Product -- `Restrict` → 有子记录时禁止删除父记录 - ---- - -## 🧭 关系查询(必须 `Include`) - -```csharp -// 多 → 一 -await _db.Products.Include(p => p.Category).FirstAsync(); - -// 一 → 多 -await _db.Categories.Include(c => c.Products).FirstAsync(); -``` - -> ⚠️ **不写 `Include` → 导航属性为 `null`** - ---- - -## ❌ 常见踩坑点 - -| 问题 | 后果 | -| ----------------------------------------------- | --------------- | -| 忘记 `Include` | 导航属性为 null | -| 导航属性不是 `public` | EF Core 不识别 | -| 外键名不精确(如 `Categoryid` vs `CategoryId`) | 关系不成立 | -| `HasOne/WithMany` 配反 | 运行时关联错乱 | - ---- - -## ✅ 验证关系是否生效 - -1. **看 SQLite Viewer**:`Products` 表必须有 `CategoryId` 列 -2. **看迁移文件**:`Migrations/xxx_Init.cs` 中应有 - ```csharp - table.ForeignKey( - name: "FK_Products_Categories_CategoryId", - column: x => x.CategoryId, - principalTable: "Categories", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - ``` - -> 🚫 **不要再执行** `dotnet ef migrations add AddRelationship` — 关系已在第 2 章存在,再生成会是空迁移。 - ---- - -## 📌 一句话总结 - -> **一对多关系 = 集合导航(一)+ 引用导航+外键(多),查询必带 `Include`,配置推荐 `OnModelCreating` 明确写法。** - - -# 作业 -无 \ No newline at end of file -- Gitee From 3cfb80c8bf7b2437aba06748a9a984bc2c3d2567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=81=A9=E7=94=9F?= <2156286470@qq.com> Date: Sun, 14 Jun 2026 23:40:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" | 0 ...0\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" | 0 .../20260604\347\254\224\350\256\260-nuget\345\214\205.md" | 0 .../20260605\347\254\224\350\256\260-CRUD.md" | 0 ...0\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename "20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" => "\351\231\210\346\201\251\347\224\237/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" (100%) rename "20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" => "\351\231\210\346\201\251\347\224\237/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" (100%) rename "20260604\347\254\224\350\256\260-nuget\345\214\205.md" => "\351\231\210\346\201\251\347\224\237/20260604\347\254\224\350\256\260-nuget\345\214\205.md" (100%) rename "20260605\347\254\224\350\256\260-CRUD.md" => "\351\231\210\346\201\251\347\224\237/20260605\347\254\224\350\256\260-CRUD.md" (100%) rename "20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" => "\351\231\210\346\201\251\347\224\237/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" (100%) diff --git "a/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" "b/\351\231\210\346\201\251\347\224\237/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" similarity index 100% rename from "20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" rename to "\351\231\210\346\201\251\347\224\237/20260601\347\254\224\350\256\260-\345\256\211\350\243\205SDK.md" diff --git "a/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" "b/\351\231\210\346\201\251\347\224\237/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" similarity index 100% rename from "20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" rename to "\351\231\210\346\201\251\347\224\237/20260603\347\254\224\350\256\260-\345\210\233\345\273\272\351\241\271\347\233\256.md" diff --git "a/20260604\347\254\224\350\256\260-nuget\345\214\205.md" "b/\351\231\210\346\201\251\347\224\237/20260604\347\254\224\350\256\260-nuget\345\214\205.md" similarity index 100% rename from "20260604\347\254\224\350\256\260-nuget\345\214\205.md" rename to "\351\231\210\346\201\251\347\224\237/20260604\347\254\224\350\256\260-nuget\345\214\205.md" diff --git "a/20260605\347\254\224\350\256\260-CRUD.md" "b/\351\231\210\346\201\251\347\224\237/20260605\347\254\224\350\256\260-CRUD.md" similarity index 100% rename from "20260605\347\254\224\350\256\260-CRUD.md" rename to "\351\231\210\346\201\251\347\224\237/20260605\347\254\224\350\256\260-CRUD.md" diff --git "a/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" "b/\351\231\210\346\201\251\347\224\237/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" similarity index 100% rename from "20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" rename to "\351\231\210\346\201\251\347\224\237/20260608\347\254\224\350\256\260-\345\257\274\350\210\252\345\261\236\346\200\247.md" -- Gitee