当前位置:首页 > 技术 > 正文内容

EF Core 数据库架构同步策略与实战

访客 技术 2026年10月13日 1

Entity Framework Core 提供了两种核心机制来维护数据模型与数据库结构的一致性。选择哪种方案取决于项目以哪一方作为权威来源:

  • 模型优先(Code First):通过迁移(Migration)逐步将模型变更应用到数据库,适合迭代频繁的小型项目
  • 数据库优先(Database First):通过反向工程(Reverse Engineering)从现有库生成实体类,适合已有成熟数据库的中大型系统

一、数据迁移实战

迁移机制允许以增量方式更新数据库结构,同时保留现有数据。其核心流程如下:

  1. 开发者执行命令生成迁移文件,描述模型与当前状态的差异
  2. 迁移文件纳入版本控制,支持团队协作
  3. 执行更新命令时,EF Core 通过 __EFMigrationsHistory 表追踪已应用的变更

工具安装配置

推荐使用跨平台的 .NET CLI 工具:

# 全局安装
dotnet tool install -g dotnet-ef --version 8.0.0

# 后续更新
dotnet tool update -g dotnet-ef

# 项目依赖
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Tools

# 验证
dotnet ef

常用参数速查:

参数简写作用
--context-c指定 DbContext 类(多上下文场景必需)
--project-p目标项目路径
--startup-project-s启动项目路径
--no-build跳过编译(确保已最新构建)
--verbose-v详细输出

Visual Studio 用户可选用包管理器控制台:

Install-Package Microsoft.EntityFrameworkCore.Tools
Get-Help about_EntityFrameworkCore

首个迁移创建

假设存在如下实体:

public class Article
{
    public int ArticleId { get; set; }
    public string Title { get; set; } = string.Empty;
}

生成初始迁移:

# CLI 方式
dotnet ef migrations add InitialSchema

# 包管理器控制台
Add-Migration InitialSchema

EF Core 将在项目根目录创建 Migrations 文件夹,包含三个关键文件:

  • XXXXXXXXXXXXXX_InitialSchema.cs:具体的 Up/Down 操作
  • XXXXXXXXXXXXXX_InitialSchema.Designer.cs:迁移元数据
  • AppDbContextModelSnapshot.cs:当前模型快照

应用至数据库:

dotnet ef database update      # CLI
Update-Database                # VS 控制台

模型迭代演进

需求变更:为 Article 添加发布时间字段

public class Article
{
    public int ArticleId { get; set; }
    public string Title { get; set; } = string.Empty;
    public DateTimeOffset PublishedAt { get; set; }
}

生成差异迁移:

dotnet ef migrations add AddArticlePublishedTime

EF Core 自动比对模型快照,识别新增字段并生成相应的 ALTER TABLE 语句。再次执行 database update 即可同步。

高级迁移技巧

排除特定表(EF Core 5.0+):

跨上下文共享表时,避免重复生成迁移:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<SharedEntity>()
           .ToTable("SharedTable", t => t.ExcludeFromMigrations());
}

自定义输出路径:

dotnet ef migrations add Init --output-dir Data/Migrations --namespace MyApp.Data.Migrations

迁移管理:

dotnet ef migrations list          # 查看所有迁移
dotnet ef migrations remove        # 删除最新未应用的迁移(已应用则失败)

迁移重置(谨慎操作):

  1. 删除 Migrations 目录
  2. 清空数据库 __EFMigrationsHistory 表
  3. 创建新的初始迁移 dotnet ef migrations add ConsolidatedInit
  4. 生成 SQL 脚本,提取其中的 INSERT 语句
  5. 手动向历史表插入该迁移记录(标记为已执行)

⚠️ 警告:重置会丢失所有自定义迁移代码,需提前备份复杂的数据操作逻辑。

二、生产环境部署策略

直接执行 database update 仅适合开发环境。生产部署推荐生成 SQL 脚本:

dotnet ef migrations script          # 完整脚本:空库 → 最新
dotnet ef migrations script 0        # 同上,显式指定起始
dotnet ef migrations script 20240101000000_AddFeature  # 从指定版本到最新

脚本优势:

  • 可人工审核,避免误删数据
  • 支持 DBA 审核与版本归档
  • 集成 CI/CD 流水线

三、反向工程(Database First)

从现有数据库生成实体类和上下文:

前置条件

  • 安装对应数据库的 EF Core 提供程序(如 Microsoft.EntityFrameworkCore.SqlServer)
  • 确保 Microsoft.EntityFrameworkCore.Design 已引用

基础命令

dotnet ef dbcontext scaffold "Server=.;Database=BlogDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer

Visual Studio 等效命令:

Scaffold-DbContext 'Server=.;Database=BlogDb;Trusted_Connection=True;' Microsoft.EntityFrameworkCore.SqlServer

精细控制选项

功能CLI 参数PMC 参数
指定表--table Users --table Posts-Tables Users,Posts
指定架构--schema dbo --schema sales-Schemas dbo,sales
保留原名--use-database-names-UseDatabaseNames
上下文名称--context BlogContext-Context BlogContext
实体输出目录--output-dir Entities-OutputDir Entities
上下文输出目录--context-dir Data-ContextDir Data
命名空间--namespace MyApp.Core-Namespace MyApp.Core
上下文命名空间--context-namespace MyApp.Data-ContextNamespace MyApp.Data

完整示例:

dotnet ef dbcontext scaffold "连接字符串" Microsoft.EntityFrameworkCore.SqlServer \
    --context AppDbContext \
    --context-dir Data \
    --output-dir Domain/Entities \
    --namespace MyProject.Domain \
    --context-namespace MyProject.Data \
    --table Articles \
    --table Categories \
    --use-database-names

注意:PowerShell 中需对 $ 字符转义,而非反斜杠。

四、方案选型建议

场景推荐方案理由
全新项目,团队熟悉 ORMCode First 迁移版本控制友好,迭代灵活
遗留系统,数据库已成熟Database First快速接入,避免重构风险
DBA 主导,变更需审批迁移 + SQL 脚本可审计,符合合规要求
微服务,多团队共享库混合策略核心表反向工程,扩展字段迁移管理
返回列表

上一篇:利用 Canal 构建 MySQL 增量数据同步方案

没有最新的文章了...

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。