文档
EF Core 毕设入门教程——数据库操作最佳实践
前言
Entity Framework Core 是 .NET 生态的 ORM 框架,让 C# 开发者用面向对象的方式操作数据库。毕设后端几乎必用它。
第一章:Code First vs DB First
Code First(毕设推荐)
// 1. 先写 C# 模型类
public class User { public int Id; public string Name; }
// 2. EF Core 自动生成数据库表
dotnet ef migrations add InitialCreate
dotnet ef database update
优点:版本可控、适合团队协作、代码即文档。
DB First(已有数据库)
dotnet ef dbcontext scaffold "Data Source=existing.db" Microsoft.EntityFrameworkCore.Sqlite
第二章:数据关系建模
一对一
public class User {
public int Id { get; set; }
public Profile? Profile { get; set; }
}
public class Profile {
public int Id { get; set; }
public int UserId { get; set; }
public User User { get; set; } = null!;
}
一对多
public class Category {
public int Id { get; set; }
public List<Product> Products { get; set; } = new();
}
public class Product {
public int Id { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; } = null!;
}
多对多(EF Core 5+ 自动处理)
public class Student {
public int Id { get; set; }
public List<Course> Courses { get; set; } = new();
}
public class Course {
public int Id { get; set; }
public List<Student> Students { get; set; } = new();
}
第三章:查询优化
急加载(避免 N+1 查询)
// 差:N+1 查询
var students = await db.Students.ToListAsync(); // 1次
foreach (var s in students)
Console.WriteLine(s.Courses.Count); // 每次循环1次!
// 好:一次查询
var students = await db.Students
.Include(s => s.Courses)
.ToListAsync();
投影查询(只取需要的字段)
var summaries = await db.Students
.Select(s => new { s.Name, s.Score })
.ToListAsync();
// 生成的 SQL:SELECT Name, Score FROM Students
分页
int page = 1, pageSize = 20;
var pageData = await db.Students
.OrderBy(s => s.Id)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
第四章:事务与并发
事务
using var transaction = await db.Database.BeginTransactionAsync();
try {
db.Orders.Add(order);
db.Inventory.Remove(stock);
await db.SaveChangesAsync();
await transaction.CommitAsync();
} catch {
await transaction.RollbackAsync();
}
乐观并发(防止数据覆盖)
public class Student {
public int Id { get; set; }
[ConcurrencyCheck]
public byte[] Version { get; set; } = Array.Empty<byte>();
}
第五章:毕设最佳实践清单
- ✅ 使用 SQLite 开发(零配置),答辩前可切换到 SQL Server/PostgreSQL
- ✅
appsettings.json配置连接字符串,不要硬编码 - ✅ 开发环境开启日志看 SQL:
options.LogTo(Console.WriteLine) - ✅ 及时
using或DisposeDbContext - ✅ 生产环境用 Migration 而非
EnsureCreated
思考题
FindAsync()和FirstOrDefaultAsync()的区别?- 什么是 N+1 查询问题?如何用
Include解决? - DbContext 的生命周期应该怎么管理(Transient / Scoped / Singleton)?