DbContext 与 DbSet 基础
设置 DbContext,定义实体,配置连接字符串,并运行第一个查询。
DbContext 与 DbSet 基础 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
什么是 Entity Framework Core
EF Core 是官方的 .NET 对象关系映射器(ORM)。它将 C# 类(实体)映射到数据库表,并允许您使用 LINQ 查询和保存数据——对于大多数操作都无需编写 SQL。
定义实体
实体是一个普通的 C# 类,其属性会映射到数据库列。按照约定,名为 Id 或 <TypeName>Id 的属性会成为主键。
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public decimal Price { get; set; }
public int Stock { get; set; }
public DateTime CreatedAt { get; set; }
}创建 DbContext
DbContext 是访问数据库的入口。它为每个实体保存 DbSet<T> 属性,并管理连接、变更跟踪和事务。
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
public DbSet<Product> Products => Set<Product>();
public DbSet<Order> Orders => Set<Order>();
}使用 DI 注册 DbContext
调用 AddDbContext,将上下文注册为作用域服务并配置数据库提供程序。
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("Default")));
// For SQLite (great for development/testing):
// options.UseSqlite("Data Source=app.db");使用 DbSet 的基本查询
DbSet<T> 提供 LINQ 运算符。查询在枚举之前不会执行(await ...ToListAsync())。这称为延迟执行。
public class ProductService
{
private readonly AppDbContext _db;
public ProductService(AppDbContext db) => _db = db;
public async Task<List<Product>> GetExpensiveAsync(decimal minPrice)
{
return await _db.Products
.Where(p => p.Price >= minPrice)
.OrderBy(p => p.Name)
.ToListAsync();
}
}按主键查找
FindAsync 会先检查本地更改跟踪器缓存,然后才访问数据库。按主键查询时使用它,可以避免不必要的数据库往返。
var product = await _db.Products.FindAsync(42);
if (product is null)
throw new KeyNotFoundException("Product not found");
// For complex keys, pass all key values:
var orderLine = await _db.OrderLines.FindAsync(orderId, productId);添加新记录
调用 Add 将实体加入待插入队列,然后调用 SaveChangesAsync 提交。EF Core 会生成 INSERT SQL,并填充自动生成的 Id。
var product = new Product
{
Name = "Mechanical Keyboard",
Price = 149.99m,
Stock = 50,
CreatedAt = DateTime.UtcNow
};
_db.Products.Add(product);
await _db.SaveChangesAsync();
Console.WriteLine(product.Id); // Auto-generated PK更新记录
由 EF Core 加载的实体会被跟踪。直接修改属性,然后调用 SaveChangesAsync——EF Core 会检测更改并生成经过优化的 UPDATE 语句。
var product = await _db.Products.FindAsync(42);
if (product is not null)
{
product.Price = 129.99m;
product.Stock -= 1;
await _db.SaveChangesAsync(); // UPDATE Products SET Price=...
}删除记录
调用 Remove 将实体标记为待删除,然后调用 SaveChangesAsync。对于批量删除,可以使用 ExecuteDeleteAsync(.NET 7+),而无需加载实体。
// Delete a tracked entity
_db.Products.Remove(product);
await _db.SaveChangesAsync();
// Bulk delete without loading (EF Core 7+)
await _db.Products
.Where(p => p.Stock == 0)
.ExecuteDeleteAsync();使用流式 API 配置
重写 OnModelCreating,使用流式 API 配置实体,包括表名、列类型、约束、索引和关系。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>(entity =>
{
entity.ToTable("products");
entity.Property(p => p.Name).IsRequired().HasMaxLength(200);
entity.Property(p => p.Price).HasColumnType("decimal(18,2)");
entity.HasIndex(p => p.Name);
});
}实战:使用 DbContext 的仓储
典型的仓储会封装 DbContext,集中管理数据访问逻辑,并将查询细节排除在服务类之外。
public class ProductRepository : IProductRepository
{
private readonly AppDbContext _db;
public ProductRepository(AppDbContext db) => _db = db;
public async Task<Product?> GetByIdAsync(int id)
=> await _db.Products.AsNoTracking().FirstOrDefaultAsync(p => p.Id == id);
public async Task<List<Product>> SearchAsync(string query)
=> await _db.Products
.Where(p => p.Name.Contains(query))
.AsNoTracking()
.ToListAsync();
}快速检查
使用 EF Core 查询时,AsNoTracking() 的作用是什么?
回顾:DbContext 与 DbSet 基础
核心要点:
- DbContext 是与数据库交互的会话;DbSet<T> 表示一张表
- 在 DI 中使用
AddDbContext注册;默认情况下它是作用域服务 - LINQ 查询采用延迟执行——使用
ToListAsync、FirstOrDefaultAsync执行 - 更改跟踪通过 SaveChangesAsync 实现自动 UPDATE/DELETE
- 对于只读查询,使用
AsNoTracking()可以提升性能
常见问题解答
「DbContext 与 DbSet 基础」课时是免费的吗?
是的 — 「DbContext 与 DbSet 基础」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「DbContext 与 DbSet 基础」这节课中我会学到什么?
设置 DbContext,定义实体,配置连接字符串,并运行第一个查询。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「DbContext 与 DbSet 基础」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- DbContext 与 DbSet 基础
- 迁移与架构管理
- 使用 EF Core 执行 CRUD 操作
- 关系:一对多与多对多