Appearance
EF Core 是什么
Entity Framework Core 是 .NET 平台的现代化对象关系映射(ORM)框架
📖 核心概念
什么是 ORM?
ORM(Object-Relational Mapping) 是一种编程技术,用于在面向对象编程语言和关系数据库之间建立映射关系。它允许开发者:
- 使用面向对象的方式操作数据库
- 无需编写大量 SQL 代码
- 自动处理数据类型转换
- 提供数据库抽象层
┌─────────────────────────────────────┐
│ 应用程序(C# 对象) │
│ │
│ var user = new User │
│ { │
│ Name = "张三", │
│ Email = "zhang@example.com" │
│ }; │
└──────────────┬──────────────────────┘
│ ORM 自动映射
▼
┌─────────────────────────────────────┐
│ 数据库(关系表) │
│ │
│ INSERT INTO Users │
│ (Name, Email) │
│ VALUES ('张三', 'zhang@...') │
└─────────────────────────────────────┘EF Core 的定义
Entity Framework Core 是微软开发的轻量级、可扩展、开源的 ORM 框架,具有以下特点:
✅ 跨平台:支持 Windows、Linux、macOS
✅ 多数据库:SQL Server、PostgreSQL、MySQL、SQLite、Cosmos DB 等
✅ LINQ 支持:使用强类型 LINQ 查询
✅ 变更跟踪:自动检测实体状态变化
✅ 迁移系统:代码优先的数据库版本控制
✅ 异步编程:完整的 async/await 支持
🏗️ 架构定位
EF Core 在技术栈中的位置
┌──────────────────────────────────────┐
│ 表现层(ASP.NET Core MVC) │
└──────────────┬───────────────────────┘
│
┌──────────────▼───────────────────────┐
│ 业务逻辑层(Services) │
└──────────────┬───────────────────────┘
│
┌──────────────▼───────────────────────┐
│ 数据访问层(EF Core + DbContext) │ ← EF Core 的位置
└──────────────┬───────────────────────┘
│
┌──────────────▼───────────────────────┐
│ 数据库(SQL Server 等) │
└──────────────────────────────────────┘与传统 ADO.NET 对比
| 特性 | ADO.NET | EF Core |
|---|---|---|
| 抽象级别 | 低级(直接操作 SQL) | 高级(面向对象) |
| 开发效率 | 低(手写 SQL) | 高(LINQ 查询) |
| 性能 | 最优(无开销) | 良好(有少量开销) |
| 类型安全 | 弱(字符串拼接) | 强(编译时检查) |
| 数据库移植性 | 差(SQL 方言) | 好(自动适配) |
| 学习曲线 | 陡峭 | 平缓 |
示例对比:
csharp
// ❌ ADO.NET:繁琐且容易出错
using (var connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (var command = new SqlCommand(
"SELECT Id, Name, Email FROM Users WHERE Age > @age", connection))
{
command.Parameters.AddWithValue("@age", 18);
using (var reader = await command.ExecuteReaderAsync())
{
var users = new List<User>();
while (await reader.ReadAsync())
{
users.Add(new User
{
Id = reader.GetInt32(0),
Name = reader.GetString(1),
Email = reader.GetString(2)
});
}
return users;
}
}
}
// ✅ EF Core:简洁且类型安全
var users = await context.Users
.Where(u => u.Age > 18)
.Select(u => new { u.Id, u.Name, u.Email })
.ToListAsync();🎯 适用场景
✅ 适合使用 EF Core 的场景
企业级应用
- ERP 系统
- CRM 系统
- OA 办公系统
Web 应用
- ASP.NET Core Web API
- Blazor 应用
- MVC/Razor Pages
快速原型开发
- MVP 产品
- 创业项目
- 内部工具
复杂业务逻辑
- 需要事务支持
- 复杂的领域模型
- DDD 架构
⚠️ 谨慎使用 EF Core 的场景
高性能要求
- 高频交易系统
- 实时数据处理
- 游戏服务器
简单 CRUD
- 小型工具应用
- 一次性脚本
非关系型数据
- 文档数据库
- 键值存储
- 图数据库
💡 混合方案
在实际项目中,可以结合使用:
csharp
// 大部分操作使用 EF Core
var orders = await context.Orders
.Include(o => o.Items)
.Where(o => o.CustomerId == customerId)
.ToListAsync();
// 高性能要求的使用原生 SQL
var result = await context.Database
.SqlQueryRaw<OrderSummary>(
"EXEC GetOrderSummary @CustomerId",
new SqlParameter("@CustomerId", customerId))
.ToListAsync();🔑 核心组件
1. DbContext
DbContext 是 EF Core 的核心类,表示与数据库的会话。
csharp
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
// DbSet 表示数据库中的表
public DbSet<Product> Products => Set<Product>();
public DbSet<Category> Categories => Set<Category>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 配置实体映射
modelBuilder.Entity<Product>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Name).HasMaxLength(100);
});
}
}职责:
- 管理数据库连接
- 跟踪实体状态
- 生成并执行 SQL
- 处理事务
2. DbSet<T>
DbSet<T> 表示数据库中某个实体类型的集合(对应一张表)。
csharp
// 查询
var products = await context.Products.ToListAsync();
// 添加
context.Products.Add(newProduct);
await context.SaveChangesAsync();
// 更新
product.Price = 99.99m;
await context.SaveChangesAsync();
// 删除
context.Products.Remove(product);
await context.SaveChangesAsync();3. 实体(Entity)
实体是映射到数据库表的 C# 类。
csharp
public class Product
{
public int Id { get; set; } // 主键
public string Name { get; set; } // 产品名称
public decimal Price { get; set; } // 价格
public int CategoryId { get; set; } // 外键
// 导航属性
public Category Category { get; set; }
}4. LINQ 查询提供器
将 LINQ 表达式翻译为 SQL 查询。
csharp
// C# LINQ
var expensiveProducts = await context.Products
.Where(p => p.Price > 100)
.OrderByDescending(p => p.Price)
.Take(10)
.ToListAsync();
// 翻译为 SQL
// SELECT TOP 10 * FROM Products
// WHERE Price > 100
// ORDER BY Price DESC🌟 主要优势
1. 提高开发效率
- 减少样板代码:无需手写 CRUD SQL
- 智能提示:IDE 提供完整的 IntelliSense
- 编译时检查:早发现错误
csharp
// 编译时就能发现错误
var users = await context.Users
.Where(u => u.Age > 18) // 如果 Age 不存在,编译失败
.ToListAsync();2. 数据库无关性
轻松切换数据库提供程序:
csharp
// SQL Server
options.UseSqlServer(connectionString);
// PostgreSQL
options.UseNpgsql(connectionString);
// MySQL
options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
// SQLite
options.UseSqlite(connectionString);3. 强大的迁移系统
bash
# 代码变更自动生成迁移
dotnet ef migrations add AddUserEmail
# 一键应用迁移
dotnet ef database update4. 内置性能优化
- 变更跟踪:只更新修改的字段
- 延迟加载:按需加载关联数据
- 缓存机制:复用查询计划
⚠️ 注意事项
1. 学习曲线
虽然比传统 ADO.NET 简单,但仍需掌握:
- LINQ 语法
- 实体关系映射
- 性能优化技巧
- 迁移管理
2. 性能开销
EF Core 引入了一些开销:
- 对象映射
- 变更跟踪
- SQL 生成
解决方案:
- 使用
AsNoTracking()进行只读查询 - 避免 N+1 查询问题
- 合理使用索引
3. 复杂查询限制
某些复杂 SQL 难以用 LINQ 表达:
- 递归查询
- 窗口函数
- 复杂的子查询
解决方案:使用原始 SQL
csharp
var result = await context.Database
.SqlQueryRaw<MyDto>("EXEC ComplexProcedure @param", param)
.ToListAsync();📊 EF Core vs EF 6 对比
| 特性 | EF Core | EF 6 |
|---|---|---|
| 平台 | 跨平台 | 仅 Windows |
| 性能 | 更优 | 一般 |
| 新功能 | 持续更新 | 维护模式 |
| 数据库支持 | 多种数据库 | 主要 SQL Server |
| 批量操作 | ✅ 原生支持 | ❌ 需第三方库 |
| JSON 列 | ✅ 支持 | ❌ 不支持 |
| 推荐度 | ⭐⭐⭐⭐⭐ | ⭐⭐ |
建议:新项目一律使用 EF Core,旧项目考虑迁移。
🚀 快速体验
5 分钟上手示例
1. 创建项目
bash
dotnet new console -n EfCoreDemo
cd EfCoreDemo
dotnet add package Microsoft.EntityFrameworkCore.SqlServer2. 定义实体
csharp
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}3. 创建 DbContext
csharp
public class AppDbContext : DbContext
{
public DbSet<Product> Products => Set<Product>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=DemoDb");
}
}4. 使用
csharp
using var context = new AppDbContext();
// 创建数据库
await context.Database.EnsureCreatedAsync();
// 添加数据
context.Products.Add(new Product { Name = "Laptop", Price = 999.99m });
await context.SaveChangesAsync();
// 查询数据
var products = await context.Products.ToListAsync();
foreach (var product in products)
{
Console.WriteLine($"{product.Name}: ${product.Price}");
}📚 延伸阅读
💡 小结
EF Core 是什么?
- 现代化的 .NET ORM 框架
- 跨平台、高性能、易扩展
为什么要学 EF Core?
- 提高开发效率 50%+
- 企业级项目的标准选择
- .NET 生态的核心技能
下一步做什么?
提示:理论只是开始,动手实践才是关键!