共计 2251 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在传统数据库开发中,开发者需要手动编写 SQL 脚本来创建和维护数据库表结构。这种方式存在以下问题:

- 容易出错:手动编写 SQL 语句时,字段类型、长度等细节容易遗漏或错误
- 效率低下:每次表结构变更都需要重新编写 SQL 脚本
- 维护困难:随着项目迭代,大量 SQL 脚本难以管理和版本控制
- 一致性差:代码模型与数据库表结构容易产生差异
技术对比:Code First vs Database First
Entity Framework Core 提供了两种主要的工作流:
- Code First(代码优先)
- 优点:
- 以代码为中心,更符合面向对象思维
- 自动生成数据库结构,减少手动 SQL 编写
- 便于版本控制和团队协作
-
缺点:
- 对现有数据库支持较弱
- 需要学习迁移命令
-
Database First(数据库优先)
- 优点:
- 适合已有数据库的项目
- 能充分利用现有数据库设计
- 缺点:
- 模型更新需要重新生成
- 对数据库设计依赖性强
核心实现
模型类定义规范
模型类应遵循以下规范:
// 商品模型示例
public class Product
{
// 主键
public int Id {get; set;}
// 必需字段,最大长度 100
[Required, MaxLength(100)]
public string Name {get; set;}
// 价格,精度 18,小数位 2
[Column(TypeName = "decimal(18,2)")]
public decimal Price {get; set;}
// 外键关系
public int CategoryId {get; set;}
public Category Category {get; set;}
}
DbContext 配置要点
DbContext 是 EF Core 的核心,负责模型到数据库的映射:
public class AppDbContext : DbContext
{public DbSet<Product> Products { get; set;}
public DbSet<Category> Categories {get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// 配置 SQL Server 连接字符串
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=MyShop;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 配置复合主键
modelBuilder.Entity<OrderItem>()
.HasKey(oi => new { oi.OrderId, oi.ProductId});
// 配置一对一关系
modelBuilder.Entity<Product>()
.HasOne(p => p.Detail)
.WithOne(d => d.Product)
.HasForeignKey<ProductDetail>(d => d.ProductId);
}
}
迁移命令详解
-
安装 EF Core 工具
dotnet tool install --global dotnet-ef -
创建初始迁移
dotnet ef migrations add InitialCreate -
应用迁移到数据库
dotnet ef database update
生产环境考量
迁移脚本的版本控制
- 将迁移文件 (.cs 和.Designer.cs) 纳入源代码管理
- 团队协作时按顺序应用迁移
- 使用
dotnet ef migrations script生成 SQL 脚本用于部署
敏感数据处理
- 不要在模型类中直接存储密码等敏感信息
- 使用数据注解
[DataType(DataType.Password)]标记敏感字段 - 考虑使用加密列或专门的密钥管理系统
性能优化建议
- 批量操作时使用
AddRange/RemoveRange - 查询时使用
AsNoTracking避免不必要的变更跟踪 - 适当使用
Take/Skip实现分页
避坑指南
- 迁移失败:删除 Migrations 文件夹并重新创建迁移
- 连接字符串错误:检查数据库服务是否运行
- 模型变更未生效:确保 DbContext 已重新编译
- 外键约束冲突:检查导航属性配置是否正确
进阶思考
自定义表名和字段
[Table("tbl_products")]
public class Product
{[Column("prod_name")]
public string Name {get; set;}
}
自定义索引
modelBuilder.Entity<Product>()
.HasIndex(p => p.Name)
.IsUnique();
种子数据
modelBuilder.Entity<Category>().HasData(new Category { Id = 1, Name = "Electronics"},
new Category {Id = 2, Name = "Clothing"}
);
实践练习建议
- 创建一个简单的博客系统模型(Post, Comment, Tag)
- 实践从模型生成数据库的完整流程
- 尝试添加一个字段并生成新的迁移
- 探索反向工程(从现有数据库生成模型)
- 实现一个包含复杂关系(多对多)的模型
通过掌握 EF Core 的 Code First 方法,开发者可以大幅提升数据库开发效率,将更多精力集中在业务逻辑实现上。随着实践深入,可以进一步探索 EF Core 的高级特性,如并发控制、延迟加载、原始 SQL 查询等,构建更健壮的数据访问层。
正文完
发表至: 未分类
近两天内
