Entity Framework Core 数据库与模型同步操作指南

📖 文档说明

本文档整理自关于使用 Entity Framework Core 命令行工具 (dotnet ef) 进行数据库与数据模型同步的完整对话,涵盖从基础概念到实际工作流程的详细说明。

适用场景: - 数据库结构已存在,需要生成对应数据模型(反向工程/Scaffolding) - 数据库结构变更后,需要更新项目中的数据模型 - 需要理解 dotnet ef database update 命令的作用

1. 核心命令:dotnet ef database update

1.1 命令含义

dotnet ef database update 是一个 Entity Framework Core 命令行命令,用于将数据库架构更新到迁移(Migrations)记录中的最新版本。

1.2 工作原理

  1. 检查迁移历史 - 查看数据库中已应用的迁移
  2. 应用未执行的迁移 - 找到所有尚未应用到数据库的迁移
  3. 执行SQL脚本 - 运行相应的迁移代码来修改数据库结构

1.3 典型工作流程

# 1. 修改数据模型(C#类)
# 2. 创建迁移
dotnet ef migrations AddYourMigrationName

# 3. 检查生成的迁移代码(可选)
# 4. 应用迁移
dotnet ef database update

# 恢复到特定迁移版本
dotnet ef database update InitialCreate

2. 反向工程:从数据库生成数据模型

2.1 初次生成数据模型

当数据库结构已存在时,使用反向工程(Scaffolding)生成对应的数据模型。

安装与设置

# 安装 EF Core 命令行工具(全局)
dotnet tool install --global dotnet-ef

# 添加必要的 NuGet 包(在项目目录中)
# 对于 SQL Server
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design

执行反向工程

dotnet ef dbcontext scaffold "Server=你的服务器;Database=你的数据库;User Id=用户名;Password=密码;" Microsoft.EntityFrameworkCore.SqlServer

2.2 常用命令选项

选项 作用 示例
-o (或 --output-dir) 指定生成文件的输出目录 -o Models
--context-dir 指定 DbContext 文件的输出目录 --context-dir Data
--table (或 -t) 仅为指定的生成模型(可多次使用) --table Users --table Posts
--schema 仅为指定的模式生成模型(可多次使用) --schema admin
--data-annotations 使用数据注解(而非 Fluent API)配置模型 --data-annotations
--force (或 -f) 强制覆盖已存在的模型文件 --force

示例:定制化生成

# 只为指定表生成模型,并放到指定目录
dotnet ef dbcontext scaffold "连接字符串" Microsoft.EntityFrameworkCore.SqlServer -o Models --table Users --table Products

3. 数据库结构更新后的重新生成

3.1 重新生成命令

当数据库结构更新后,需要重新执行 scaffold 命令来同步变更:

# 基本重新生成命令
dotnet ef dbcontext scaffold "你的连接字符串" Microsoft.EntityFrameworkCore.SqlServer --force

# 推荐:指定输出目录并使用强制覆盖
dotnet ef dbcontext scaffold "你的连接字符串" Microsoft.EntityFrameworkCore.SqlServer -o Models --force --context-dir Data

3.2 重要注意事项

1. 备份自定义代码

重新生成会覆盖所有生成的类,包括: - 所有实体类(.cs 文件) - DbContext

如果这些类中有自定义代码,它们会被覆盖丢失!

2. 处理自定义代码的策略

方案A:使用部分类(推荐)

// 自动生成的 User.cs(会被覆盖)
public partial class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// 手动创建的 UserExtensions.cs(不会被覆盖)
public partial class User
{
    public string GetFullName() => $"{FirstName} {LastName}";

    // 自定义业务逻辑
    public bool IsActive() => Status == "Active";
}

方案B:继承 DbContext

// 自动生成的 ApplicationDbContext.cs
public partial class ApplicationDbContext : DbContext
{
    // 自动生成的代码
}

// 手动创建的 ApplicationDbContextExtensions.cs
public partial class ApplicationDbContext
{
    // 自定义方法不会被覆盖
    public IQueryable<ActiveUsers> GetActiveUsers() 
        => Users.Where(u => u.IsActive);
}

3. 选择性生成

如果只有部分表有变化,可以只生成特定表:

dotnet ef dbcontext scaffold "连接字符串" Microsoft.EntityFrameworkCore.SqlServer --table Users --table Products --force

3.3 实际工作流程

# 1. 确保备份了任何自定义修改
# 2. 执行重新生成
dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=true;" Microsoft.EntityFrameworkCore.SqlServer -o Models --force

# 3. 检查生成的文件,确保没有意外丢失自定义代码
# 4. 编译项目检查错误
dotnet build

4. 替代方案与高级建议

4.1 使用迁移(Migrations)模式

如果项目采用代码优先(Code-First)模式,可以使用迁移来管理数据库变更:

# 代码优先方式
dotnet ef migrations AddYourChanges
dotnet ef database update

4.2 创建自动化脚本

对于频繁的数据库结构变更,可创建自动化脚本:

# update-models.ps1(PowerShell脚本示例)
param(
    [string]$ConnectionString = "默认连接字符串"
)

Write-Host "备份自定义文件..."
Copy-Item "Models/Custom" "backup/Custom" -Recurse -Force

Write-Host "重新生成模型..."
dotnet ef dbcontext scaffold $ConnectionString Microsoft.EntityFrameworkCore.SqlServer -o Models --force

Write-Host "恢复自定义文件..."
Copy-Item "backup/Custom" "Models/Custom" -Recurse -Force

Write-Host "完成!"

4.3 连接字符串安全建议

不要在版本控制系统(如 Git)中提交包含密码的连接字符串。建议使用: - 用户密钥(User Secrets) - 环境变量 - Azure Key Vault(Azure 项目)

5. 故障排除与提示

5.1 常见问题

  1. 文件被锁定无法覆盖:关闭所有打开相关文件的编辑器或 IDE
  2. 连接失败:检查连接字符串格式和网络连接
  3. 权限不足:确保数据库用户有读取架构的权限

5.2 最佳实践

  1. 始终使用版本控制:在重新生成前提交当前更改
  2. 测试重新生成:在开发环境中先测试,再应用到生产代码
  3. 文档化自定义:记录对生成类所做的任何自定义修改

📝 总结

本文档提供了使用 dotnet ef 工具进行数据库与数据模型同步的完整指南,重点包括: 1. dotnet ef database update 命令的作用和使用场景 2. 使用反向工程从数据库生成数据模型的完整流程 3. 数据库结构更新后重新生成模型的方法和注意事项 4. 保护自定义代码不被覆盖的策略

通过遵循这些步骤和最佳实践,您可以高效地保持数据库结构与项目数据模型的同步。