From b5176aafe82fed66fb04f92ad0f734b863212925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AE=B6=E5=92=8C?= <1409177310@qq.com> Date: Mon, 15 Jun 2026 12:33:51 +0800 Subject: [PATCH] ds --- .../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 +++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 "\346\235\216\345\256\266\345\222\214/20260601-\345\256\211\350\243\205SDK.md" create mode 100644 "\346\235\216\345\256\266\345\222\214/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" create mode 100644 "\346\235\216\345\256\266\345\222\214/20260604-nuget\345\214\205.md" create mode 100644 "\346\235\216\345\256\266\345\222\214/20260605-CRUD.md" create mode 100644 "\346\235\216\345\256\266\345\222\214/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/\346\235\216\345\256\266\345\222\214/20260601-\345\256\211\350\243\205SDK.md" "b/\346\235\216\345\256\266\345\222\214/20260601-\345\256\211\350\243\205SDK.md" new file mode 100644 index 0000000..e6d8979 --- /dev/null +++ "b/\346\235\216\345\256\266\345\222\214/20260601-\345\256\211\350\243\205SDK.md" @@ -0,0 +1,10 @@ +## 笔记 + +安装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/\346\235\216\345\256\266\345\222\214/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" "b/\346\235\216\345\256\266\345\222\214/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" new file mode 100644 index 0000000..a1d9626 --- /dev/null +++ "b/\346\235\216\345\256\266\345\222\214/20260603-\345\210\233\345\273\272\351\241\271\347\233\256.md" @@ -0,0 +1,21 @@ +## 笔记 + +创建项目 + +在终端(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/\346\235\216\345\256\266\345\222\214/20260604-nuget\345\214\205.md" "b/\346\235\216\345\256\266\345\222\214/20260604-nuget\345\214\205.md" new file mode 100644 index 0000000..26054c7 --- /dev/null +++ "b/\346\235\216\345\256\266\345\222\214/20260604-nuget\345\214\205.md" @@ -0,0 +1,15 @@ +## 笔记 + +装 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/\346\235\216\345\256\266\345\222\214/20260605-CRUD.md" "b/\346\235\216\345\256\266\345\222\214/20260605-CRUD.md" new file mode 100644 index 0000000..dbbde0b --- /dev/null +++ "b/\346\235\216\345\256\266\345\222\214/20260605-CRUD.md" @@ -0,0 +1,21 @@ +## 笔记 + + +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/\346\235\216\345\256\266\345\222\214/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/\346\235\216\345\256\266\345\222\214/20260608-webapi\344\270\255\347\232\204\344\270\273\345\244\226\351\224\256\345\205\263\347\263\273.md" new file mode 100644 index 0000000..9799b2b --- /dev/null +++ "b/\346\235\216\345\256\266\345\222\214/20260608-webapi\344\270\255\347\232\204\344\270\273\345\244\226\351\224\256\345\205\263\347\263\273.md" @@ -0,0 +1,98 @@ +# 笔记 + +--- + +## 🧩 核心概念 + +| 概念 | 说明 | +| -------------- | --------------------------------------------------- | +| **一对多关系** | 一个实体(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