使用EF Core更新与修改生产数据库

使用EF Core的Code First,在设计阶段,直接使用Database.EnsureCreated()EnsureDeleted()可以快速删除、更新最新的数据结构。由于没有什么数据,删除的风险非常低。但是对于已经投入生产的数据库,这个方法就绝对不可行了。

考虑以下场景:

项目已经上线,一直使用本地测试数据库进行开发,本地已经增加和修改了较多数据库表结构,线上数据庞大且实时更新,现在测试完毕需要进行上线。

如果需要更新生产数据库,我能想的有两种方法:

从一开始就使用Migration

从数据库开始设计的时候,就使用EF Migration,保证数据库能够与代码同步,不过操作的时候,需要极为小心,务必要检查生成的更新数据库代码,直接连接生产数据库,

需要注意的事项:

  • 从一开始就使用Migration任何时候都不要使用Context.Database.EnsureCreated或者EnsureDeleted语句。
  • 使用Add-migration之后,不要删除生成的Migration文件,这些文件记录了数据结构的变化历史。
  • 并不是所有的变化都能自动识别,比如“修改表列名称大小写”,这种情况很多时候生成的数据是执行删除然后再新建,和我们重命名的初衷相去甚远。因此要特别检查migrationBuilder.Drop相关的页面。

使用Scaffold

如果一开始就没有使用migration进行同步的话,那么使用EF Core将无法直接更新,我们需要变通一下:

逆向数据库到模型

首先需要数据库的数据结构逆向到模型,我们使用Scaffold就可以了,详细文档就可以查看这里,需要注意的是,我们的场景下,已经有修改好的DataContext与Model,在进行scaffold的过程中,一定要指定outputdir和context,不要和当前的文件冲突。

根据自己的喜好,选择是否采用-DataAnnotations,另外也可以使用-table指定需要修改的表,没有被指定的表,将保持原样。默认EF Core会按照自己的命名规则重新命名,如果你想保留自己的套路,那么使用-UseDatabaseNames参数。

Add-Migration

输出的模型我指定放在Models文件夹,原来的Models文件夹,我改成了Models1,并且更换了命名空间以保证项目现在能够正常编译。

  • 导出的模型与DbConext:Models.Models命名空间,Models文件夹
  • 新模型与DbConext:Models命名空间,Models1文件夹
    接下来运行Add-Migration
add-migration initialcreate -context exportedContext

这样会在Migrations文件夹下面生成一个snapshot和一个migration文件。snapshot是当前数据库的跟踪,另外一个是运用update-database时系统会执行的操作。里面有一个Up()和一个Down()方法,Up是执行更新时EF对数据库的操作,Down是回滚当前更改。由于这是第一次执行add-migration,EF Core会认为数据库现在还是空的,因此两个方法都有大量的语句,我们删除所有create和drop相关的语句,我这边是全部删除了,只留下空方法。

应用迁移,同步

前面准备工作已经到位了,这一步将直接操作数据库了。使用update-database将当前的migration更新到数据库,由于我们现在的数据结构和生产数据库的数据结构一模一样,实际上我们不需要执行什么操作(删除了Up、Down内部的代码),执行Update-Database只是让EF Core将Models和生产数据库建立联系

我理解只是添加__EFMigrationsHistory中的记录,以便EF Core后续追踪。

修改模型内容

将Models1中的文件覆盖Models中的文件,由于类型命名的差异,可能会提示一些错误,按照自己的习惯修改就好了。接下来是循序渐进,一点点修改模型,并经常add-migration,观察生成的语句是否正常。

由于我使用了Identity,在数据中有对应的AspNet开头的表,这些表我并不在本系统中使用(其他系统需要用),因此我删除了对应的模型、snapshot、DbContext记录,运行Add-Migration,生成了如下文件:

        protected override void Up(MigrationBuilder migrationBuilder){migrationBuilder.DropTable(name: "AspNetRoleClaim");migrationBuilder.DropTable(name: "AspNetUserClaim");migrationBuilder.DropTable(name: "AspNetUserLogin");migrationBuilder.DropTable(name: "AspNetUserRoles");migrationBuilder.DropTable(name: "AspNetUserToken");migrationBuilder.DropTable(name: "AspNetRole");migrationBuilder.DropTable(name: "AspNetUser");}

说明现在已经能够正常跟踪我们的修改了,不过我这里需要保留对应的表,因此删除up与down的所有内容。

注意以下几点:

更新模型名称

如果使用fluentAPI,那么模型对应的表名称会直接在fluentAPI中直接指定,只修改模型的名称没有任何效果。修改的话,可以修改对应的fluentAPI,或者换用Annotation

提示找不到constraint

对于修改主键、索引等内容的情况,如果不是通过EF Core建立的数据库,那么命名规则可能不一样。对于postgresql数据库,可以用这个查询名称,然后修改对应的migration文件内容即可。

SELECT * FROM pg_CONSTRAINT

复合主键的限制

对于使用两列或者以上列作为复合主键的情况,使用EnsureCreated方法是可以识别Annotation形式的主键的。

[Key]
[Column(Order = 1)]
public string DeviceId { get; set; }
[Key]
[Column(Order = 2)]
public long Timestamp { get; set; }

使用Migration的时候,这种形式无法识别,需要在OnModelCreating()中,使用fluentAPI

modelBuilder.Entity<DeviceData>().HasKey(w => new { w.DeviceId, w.Timestamp });

Command执行超时

默认Command执行的超时设置只有30s,对一些大一点的表来说,是不太够的。可以设置:

optionsBuilder.UseNpgsql("Server=xxxxxxxxxxxxx", opt=>opt.CommandTimeout(3000));

增加命令执行的超时时间。

多个连接字符串的情况

如果程序使用了appsettings.Development.json之类的文件存储连接字符串,那么需要指定环境是Production(生产数据库),否则可能还原到本地数据库去了。
对于nuget包管理控制台(使用update-database),执行:

$Env:ASPNETCORE_ENVIRONMENT = "Development"
Update-Database

对于使用dotnet ef工具集的,直接执行:

dotnet ef database update --environment Development

cannot be cast automatically to type

设计数据库表如果修改列的数据类型(比如从varchar到integer),Postgresql会提示这个问题,导致无法修改。可以在migrationbuilder中使用sql,按照提示添加"USING "x"::integer"解决。但是这种方法还是不太优雅,手动处理Up()之后,还需要处理Down(),否则将无法正确还原。

可以使用分步的方法进行,假设我们需要将Id从varchar改成int4

  1. 添加一个字段temp,类型为int4,设置为[Key],然后删除Id字段。
  2. 添加并应用迁移
  3. 修改temp名称为Id
  4. 添加并应用迁移

多次应用迁移

每次修改尽量少一点,然后update-database,这样更容易发现问题,对于有


这种提示的,一定要检查生成语句中Drop相关的语句。

本地数据库与生产数据库,都有__EFMigrationsHistory记录相关的迁移情况。在生产与本地数据库中进行切换时,不用担心顺序问题,Update-Database会一个个应用迁移直到最新。

总结

使用Migration能够降低数据库同步中很多工作量,合理利用,可以对生产用的数据库进行热更新。

注:本文在.NET 6,EF Core 6下测试通过。

相关内容拓展:(技术前沿)

近10年间,甚至连传统企业都开始大面积数字化时,我们发现开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。

针对这类问题,低代码把某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。极大的提高了程序员的生产效率。

推荐一款程序员都应该知道的软件JNPF快速开发平台。这是一个基于Java Boot/.Net Core构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,实现快速开发,提升工作效率;框架集成了表单、报表、图表、大屏等各种常用的Demo方便直接使用;后端框架支持Vue2、Vue3。

体验官网:https://www.jnpfsoft.com/?csdn

还没有了解低代码这项技术可以赶紧体验学习!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/108975.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

粒子群算法的基本原理和Matlab实现

1.案例背景 1.1 PSO算法介绍 粒子群优化算法(Particle Swarm Optimization,PSO)是计算智能领域,除了蚁群算法,鱼群算法之外的一种群体智能的优化算法,该算法最早是由Kennedy和 Eberhart 在1995年提出的。PSO算法源于对鸟类捕食行为的研究,鸟类捕食时,每只鸟找到食物最简单有效…

mac清理磁盘空间软件有哪些 mac清理磁盘空间怎么清理

随着时间的推移&#xff0c;Mac电脑上的文件会越来越多&#xff0c;很快就会占满磁盘空间。这时候&#xff0c;我们需要一个好的Mac清理磁盘空间软件来释放空间&#xff0c;保持电脑的良好性能。那么&#xff0c;mac清理磁盘空间软件有哪些呢&#xff1f;接下来&#xff0c;我将…

用 PHP 和 JavaScript 显示地球卫星照片

向日葵 8 号气象卫星是日本宇宙航空研究开发机构设计制造的向日葵系列卫星之一&#xff0c;重约 3500 公斤&#xff0c;设计寿命 15 年以上。该卫星于 2014 年 10 月 7 日由 H2A 火箭搭载发射成功&#xff0c;主要用于监测暴雨云团、台风动向以及持续喷发活动的火山等防灾领域。…

几个nlp的小任务(生成式任务——语言模型(CLM与MLM))

@TOC 本章节需要用到的类库 微调任意Transformers模型(CLM因果语言模型、MLM遮蔽语言模型) CLM MLM 准备数据集 展示几个数据的结构

【Spring Boot】数据库持久层框架MyBatis — MyBatis简介

MyBatis简介 本节首先会介绍什么是ORM、什么是MyBatis、MyBatis的特点以及核心概念&#xff0c;最后介绍MyBatis是如何启动、如何加载配置文件的&#xff1f; 1.什么是ORM ORM&#xff08;Object Relational Mapping&#xff0c;对象关系映射&#xff09;是为了解决面向对象…

下一代存储解决方案:湖仓一体

文章首发地址 湖仓一体是将数据湖和数据仓库相结合的一种数据架构&#xff0c;它可以同时满足大数据存储和传统数据仓库的需求。具体来说&#xff0c;湖仓一体可以实现以下几个方面的功能&#xff1a; 数据集成&#xff1a; 湖仓一体可以集成多个数据源&#xff0c;包括结构…

C++ 网络编程项目fastDFS分布式文件系统(九)总结

1. Location语法 1. 语法规则 location [ |~|~ * |^~ ] /uri/ { … } 正则表达式中的特殊字符 : - . () {} [] * ? 2. Location 优先级说明 在 nginx 的 location 和配置中 location 的顺序没有太大关系。 与 location 表达式的类型有关。 相同类型的表达式&a…

K8S最新版本集群部署(v1.28) + 容器引擎Docker部署(上)

温故知新 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目的&#x1f4d7;总体方向 &#x1f4da;第二章 基本环境信息&#x1f4d7;机器信息&#x1f4d7;软件信息&#x1f4d7;部署用户kubernetes &#x1f4da;第三章 Kubernetes各组件部署&#x1f4d7;安装kube…

BlazorServer中C#与JavaScript的相互调用

BlazorServer中C#与JavaScript的相互调用 前言&#xff1a; ​ 虽然BlazorServer中推荐使用C#在razor页面中的替代JavaScript来完成逻辑的编写&#xff0c;但当需要使用第三方的javascript文件/组件里的内容时&#xff0c;则难免要在C#中调用其方法或对象。反之当你的(用到第…

Java:HashMap、LinkedHashMap、TreeMap集合的底层原理和集合的嵌套

HashMap的底层原理 LinkedHashMap的底层原理 TreeMap集合的底层原理 集合的嵌套

Elasticsearch 8.X reindex 源码剖析及提速指南

1、reindex 源码在线地址 为方便大家验证&#xff0c;这里给出 reindex github 源码地址。 https://github.com/elastic/elasticsearch/blob/001fcfb931454d760dbccff9f4d1b8d113f8708c/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java reindex 常见…

IDEA对Web和Tomcat的一些配置

这里只是做了自己学习中的一点记录&#xff0c;仅供参考哈&#xff01; 配置Tomcat Modules新增Web 新增module后新增Artifacts 新增Artifacts后Tomcat新增布署 将指定的module由普通java项目变成web项目 直接创建布署到Tomcat时所需要的Aritifacts包 配置Servlet的依赖包 配置…

Vue2学习笔记の使用Vue脚手架

目录 使用Vue脚手架脚手架文件结构关于不同版本的Vuevue.config.js配置文件ref属性props配置项mixin(混入)插件scoped样式总结TodoList案例webStorage组件的自定义事件全局事件总线&#xff08;GlobalEventBus&#xff09;消息订阅与发布&#xff08;pubsub&#xff09;nextTic…

redis windows 版本安装

1. 下载windows安装包并解压 如果是Linux版本可以直接到官网下载&#xff0c;自3.x起官网和微软网站就没有redis安装包更新了&#xff0c;好在github有开发者在编译发布更新&#xff08;目前最新有5.0.9版本可下&#xff09;&#xff0c;地址&#xff1a;redis windows 5版本下…

Maven 基础之安装和命令行使用

Maven 的安装和命令行使用 1. 下载安装 下载解压 maven 压缩包&#xff08;http://maven.apache.org/&#xff09; 配置环境变量 前提&#xff1a;需要安装 java 。 在命令行执行如下命令&#xff1a; mvn --version如出现类似如下结果&#xff0c;则证明 maven 安装正确…

MyBatisPlus实现多租户功能

前言&#xff1a;多租户是一种软件架构技术&#xff0c;在多用户的环境下&#xff0c;共有同一套系统&#xff0c;并且要注意数据之间的隔离性。 一、SaaS多租户简介 1.1、SaaS多租户 SaaS&#xff0c;是Software-as-a-Service的缩写名称&#xff0c;意思为软件即服务&#x…

HTML之VSCode简单配置与创建

目录 插件下载 然后输入源码&#xff1a; 使用 效果 插件下载 下载这个插件后可以直接运行&#xff1a; 然后创建一个文件&#xff1a; 然后输入源码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…

Redis 10 大数据类型

1. which 10 1. redis字符串 2. redis 列表 3. redis哈希表 4. redis集合 5. redis有序集合 6. redis地理空间 7. redis基数统计 8. redis位图 9. redis位域 10. redis流 2. 获取redis常见操作指令 官网英文&#xff1a;https://redis.io/commands 官网中文&#xff1a;https:/…

9.3 功率放大电路的安全运行

在功率放大电路中&#xff0c;功放管既要流过大电流&#xff0c;又要承受高电压。例如&#xff0c;在 OCL 电路中&#xff0c;只有功放管满足式&#xff08;9.2.13&#xff09;所示极限值的要求&#xff0c;电路才能正常工作。因此&#xff0c;所谓功率放大电路的安全运行&…

【VS Code插件开发】状态栏(五)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…