EF Core Code First与SQL Server项目混合开发的CI/CD推荐方案
结论
你提出的思路完全是这类混合场景下的生产级标准实践,比继续硬扛双端维护、靠人盯规范的方案靠谱得多,完全可以落地。
为什么必须放弃当前的双源维护模式
你现在靠开发规范、代码评审拦结构漂移的模式本质是不可持续的:
- 只要有一次开发者改了SQL端的视图/存储过程忘了同步Code First实体,或者改了实体忘了更新数据库结构,轻则开发环境联调卡壳,重则线上出现字段映射错误、存储过程调用失败的故障,排查成本极高
- EF Core原生迁移对表结构的支持尚可,但对视图、存储过程、自定义函数这类可编程对象的管控能力极弱,大多时候只能靠在迁移里嵌原生SQL实现,既没有依赖校验,也没有统一的版本追踪,复杂场景下远不如专业数据库工具的管控能力。
具体落地步骤
你可以按下面的顺序推进,基本不会踩大坑:
- 先做基线对齐
以当前生产环境实际运行的数据库结构为准,把所有表、视图、存储过程、函数、索引、约束、权限配置全量导入SQL Server数据库项目(.sqlproj),作为V1.0基线。同时在Flyway/Liquibase里把这个基线标记为已执行,避免初始化时重复创建对象。
注意不要拿现有Code First的实体或者历史EF迁移文件当基线,一定要以生产库的真实结构为准,先把历史上已经出现的结构漂移全部抹平。 - 锁死唯一变更入口
之后所有数据库相关的变更,不管是表结构调整还是视图、存储过程的修改,必须先在SQL Server数据库项目里提交对应SQL脚本,彻底禁止任何人直接连接开发/测试/生产库执行DDL,也不要再用dotnet ef migrations add生成结构相关的迁移文件。
SQL Server项目本身自带编译校验,改字段时如果有依赖该字段的视图、存储过程不兼容,会直接编译报错,能把大部分结构问题拦在代码提交阶段,比人工评审靠谱得多。 - 自动同步EF实体层
把EF实体的生成步骤放到CI流程里:每次数据库项目的变更合并到主分支后,自动执行dotnet ef dbcontext scaffold命令,从最新的标准结构(可以直接连开发环境的标准库,也可以用数据库项目编译出的dacpac作为源)生成实体类和DbContext,自动提交到代码仓库的对应目录,彻底去掉人工修改EF实体的步骤,从根源上避免实体和库结构不一致。
这里注意两个细节:一是给脚手架命令加过滤规则,只生成业务层需要的对象,不要把系统表、运维专用表都生成进来;二是把自动生成的实体类都设为partial,你需要加业务注解、自定义映射配置的时候,写在单独的partial类文件里,不要修改自动生成的文件,避免下次脚手架执行时被覆盖。 - 对接现有CI/CD流程
把原来流水线里的dotnet database update步骤替换为Flyway/Liquibase的迁移步骤:- 代码合并到main分支后,先拿到版本化的SQL迁移脚本
- 先在测试环境执行迁移,跑完所有集成测试验证兼容性
- 测试通过后再按发布窗口执行生产迁移,所有迁移操作留存完整日志,提前准备好对应回滚脚本。
落地注意事项
- 不用完全抛弃EF Core的能力:业务层的增删改查还是可以正常用EF Core写,反向脚手架生成的实体和你之前手写的Code First实体使用体验完全一致,不会损失EF的任何功能
- 所有迁移脚本要做幂等处理:SQL Server 2016及以上版本直接用
CREATE OR ALTER语法写视图、存储过程,建表、加字段的逻辑先判断对象是否存在再执行,避免脚本重跑时报错 - 从权限层面兜底:生产环境的DDL权限只开放给CI/CD的执行账号,所有开发、运维人员都没有直接修改生产库结构的权限,堵死绕过流程直接改库的可能
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

