• Entity Framework Core 2.0 数据库迁移


    看见过几篇其他大神写的关于EFCore2.0的文章。本人有点小白,一开始看文档的时候除了一些基本操作外其他部分几乎没有读懂,我估计会有一部分人跟我一样,因为人家读懂了的早就懂了。

    在这里我写一下我自己的理解和观点,并基于EF6的机制做一些比较。理解可能比较表象,如果有错误希望大神们指正。

     


     

    一、迁移指令

    从EF6的经验来讲,建立完基类,接口,表和一堆服务后我们,在模型初始化方法里添加迁移模式的配置然后,直接在控制台执行Enable-Migrations就可以了。

    但是在EFCore2.0中我执行启动自动迁移,得到下面这个

    Enable-Migrations is obsolete. Use Add-Migration to start using Migrations.

    简单来说就是,Enable-Migrations过期了,让你用Add-Migration。

     

    经过了一番百度得到的诸多的文章一般都是说,在控制台执行Add-MigrationUpdate-Database两个指令。参考  EF Core 数据库迁移(Migration)

    先说下 Add-Migration 的基本用法, Add-Migration { 迁移名称 } -Context {上下文名称}

    迁移名称:我理解为迁移的版本号或版本说明一类的东西

    上下文名称:当项目中存在多个继承DBContext的类的时候需要指定上下文

    还有其他的参数这里就先不说了。

    执行 Add-Migration Update 等指令运行完,会发现项目下多了一个Migrations文件夹

    一般来讲会有三个文件(名字都是我自己起的)

    1. 变更文件:时间戳_迁移名称.cs
    2. 结构快照:时间戳_迁移名称.Designer.cs
    3. 当前快照:上下文名称ModelSnapshot.cs

    一般来讲变更文件和结构快照是配套出现的,而当前快照只有1个。随着执行迁移的次数的增加,文件数量也会越来越多。

    变更文件,是EF根据当前的模型和已有的最新的快照生成变更方法文件

    这里会涉及到两个方法,Up和Down。

    Up是更新数据库的操作图上显示的就是一个创建表。

    Down方法是回滚操作,也就是当你发现这次更新有问题的时候,回滚数据库版本(仅结构)用的。

    结构快照,EF根据当前的模型生成的数据库结构文件,这个不用去管。

    当前快照,会指向当前EF所运行的数据库迁移版本的快照,以这个为基准与数据库沟通,默认指向最新的结构快照。

    二、CodeFirst迁移数据库

    上面提到过了Enable-Migrations指令不好使了,那我们在添加迁移版本(Add-Migration)以后还要执行一下Update-Database。这个指令没啥好说的,直接执行就好。

    执行完命令,我们会发现数据库建好了。

    但是我认为这个方法非常的不方便,也不科学,为什么呢?

    试想一下,我们的开发环境肯定与运行环境不是在一起的,更不可能用同一个数据库。那么我用IDE来跟新了开发用的数据库没问题,发布完跟部署工程师说:“你要在服务器上通过命令执行一个XXX命令才能建立或更新数据库”。这个不太可能!估计说完了,你部署的同事就疯了。

    所幸在DBContext中发现了一个Database对象

    它具有一个Migrate方法,可以来启动EF的数据库更新方法。

    那我们可以修改数据库上下文的构造方法

        public class ApplicationDb : DbContext
        {
    
            public ApplicationDb(DbContextOptions<ApplicationDb> options) : base(options)
            {
                if (!Database.EnsureCreated()) //确认数据库是否被建立
                {
                    Database.Migrate();//启动迁移比对
                }
            }
    
        }

    先检测数据库是否存在,如果不存在,则直接建立数据库,不进行迁移比对。存在的话,启动比对。根据官方文档,建立后不推荐执行Migrate方法以防冲突

    这样在项目启动的时候就会自动比对迁移,并更新数据库结构。

    当然!这个代码仅用作示例!因为每次对创建DBContext兑现都去比对上下问,是对数据库一种无意义的重复开销,具体怎么封装,仁者见仁智者见智。

    我的解决方案是做一个一异步的方法,在项目的Startup中的Configure中执行,达到项目启动时执行的效果。

    三、EFCore2.0 与EF6迁移机制上的区别

    EF都会在数据库里生成一个以前版本的表

    EF6叫__MigrationHistory

    EFCore2.0叫__EFMigrationsHistory

    这两个文件都会存储迁移版本的名称,只不过EF6是自动生成的,EFCore2.0是要手动生成的。然后最关键的是Model字段。这个就是我们所谓的数据库快照。

    EF6中每次启动的时候会根据当前模型生成一个模型快照,然后与数据库中最新的快照进行比对,如果产生差异,根据差异变更数据库。

    但是在Core中并没有保存数据库快照,而是以代码的形式来保存。这就是为什么我们随着执行迁移的次数的增加,文件数量也会越来越多。那些文件都是数据库的快照。而数据库的本身只存储指向版本。

    所以跟EF6一样,我们为了减少快照所占控件,可以删除除最新以外的快照文件(只要你不想回滚)。

    四、关于迁移需要注意

    本来我是打算做一个批处理文件,注册在在项目编译前,在项目编译的时候自动生成迁移。但是目前EFCore2.0的迁移功能还不够智能。

    因为在你对字段重命名以后默认是删除字段,然后重建字段,而不是重命名字段。这点在EF6中做的还算不错。

    所以需要开发者在添加迁移以后,去检查一下Up方法的操作是否是我们想要的。当然如果你需要用到回滚那还要检查一下Down方法。

    这个希望能在以后的版本中得到改善吧。

  • 相关阅读:
    SQLSERVER 的表分区(水平) 操作记录2
    GraphQl in ASP.NET Core
    初始认知学习 .net core 逐步加深
    C# 关于使用JavaScriptSerializer 序列化与返序列化的操作
    Nginx、IIS 相关命令
    SqlServer:查询指定表所有外键关联表信息
    centos 重启宝塔命令
    c# 根据日志中的方法信息,反射再次执行相关方法
    jackson 下载地址记录
    【设计模式】六大原则
  • 原文地址:https://www.cnblogs.com/kasimlz/p/7444834.html
Copyright © 2020-2023  润新知