共计 2222 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在 C# 开发中,数据库表的创建和维护一直是一个耗时且容易出错的过程。传统的手动编写 SQL 脚本方式存在诸多问题:

- 需要开发者具备深厚的 SQL 知识
- 修改表结构时容易遗漏相关约束和索引
- 难以跟踪历史变更,回滚困难
- 开发、测试和生产环境之间的数据库同步困难
技术选型对比
Entity Framework Core Migrations 相较于其他 ORM 工具(如 Dapper、NHibernate)在数据库迁移方面的优势:
- 代码优先开发:直接从 C# 模型生成数据库结构
- 版本控制:自动记录每次迁移变更
- 跨平台支持:兼容多种数据库系统
- 命令行集成:与 dotnet CLI 无缝衔接
核心实现细节
模型定义
// 产品模型示例
public class Product
{public int Id { get; set;}
[Required]
[MaxLength(100)]
public string Name {get; set;}
[Column(TypeName = "decimal(18,2)")]
public decimal Price {get; set;}
public int Stock {get; set;}
}
DbContext 配置
public class AppDbContext : DbContext
{public DbSet<Product> Products { get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=MyShop;Trusted_Connection=True;");
}
}
迁移命令执行流程
-
安装 EF Core 工具包:
dotnet tool install --global dotnet-ef -
添加初始迁移:
dotnet ef migrations add InitialCreate -
应用迁移到数据库:
dotnet ef database update
完整代码示例
以下是一个完整的电商系统模型定义和迁移示例:
// 订单模型
public class Order
{public int Id { get; set;}
public DateTime OrderDate {get; set;}
public decimal TotalAmount {get; set;}
public ICollection<OrderItem> Items {get; set;}
}
// 订单项模型
public class OrderItem
{public int Id { get; set;}
public int ProductId {get; set;}
public Product Product {get; set;}
public int Quantity {get; set;}
public decimal UnitPrice {get; set;}
public int OrderId {get; set;}
public Order Order {get; set;}
}
// 扩展 DbContext
public class AppDbContext : DbContext
{public DbSet<Product> Products { get; set;}
public DbSet<Order> Orders {get; set;}
public DbSet<OrderItem> OrderItems {get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{optionsBuilder.UseSqlServer("YourConnectionString");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 配置关系
modelBuilder.Entity<OrderItem>()
.HasOne(oi => oi.Order)
.WithMany(o => o.Items)
.HasForeignKey(oi => oi.OrderId);
}
}
性能考量
- 迁移执行效率:
- 大型数据库迁移可能耗时较长
-
建议在低峰期执行生产环境迁移
-
并发问题处理:
- 使用事务确保迁移原子性
-
考虑使用
--connection参数指定专用连接 -
批量操作优化:
- 对于大数据量表,考虑拆分迁移步骤
- 使用
Sql("自定义 SQL")方法优化性能
生产环境避坑指南
常见错误及解决方案
- 迁移冲突:
- 现象:多人同时添加迁移导致冲突
-
解决:使用
dotnet ef migrations script生成脚本后手动合并 -
模型变更导致的失败:
- 现象:删除属性后迁移失败
-
解决:先创建迁移删除列,再删除模型属性
-
数据丢失风险:
- 现象:重命名属性导致数据丢失
- 解决:使用
[Column]属性保留原列名
最佳实践
- 为每个功能分支创建独立迁移
- 迁移前备份数据库
- 在开发环境充分测试迁移脚本
- 使用
dotnet ef migrations script预审 SQL
总结与思考
EF Core Migrations 极大简化了数据库版本管理,但要将它真正融入开发流程还需要考虑:
- 如何将迁移脚本集成到 CI/CD 流水线
- 多环境部署时的版本控制策略
- 大型团队协作时的迁移管理规范
建议从简单项目开始实践,逐步建立适合团队的迁移工作流。对于关键业务系统,仍需配合专业的数据库变更管理工具。
正文完
发表至: 编程开发
近一天内
