zoukankan      html  css  js  c++  java
  • EF Core Model更新迁移

    EF Core 迁移

    感觉就是以前EF Code First的自动同步数据库功能

    内容:在你新增、更新TableModel后,如何自动化的更新DB中的真实Table。以及对这些更改进行一个版本控制。

    本文将以一个示例进行简单明了的演示输出。(不会很详细,只记录主要步骤)

    当下我们已经有了一个ASP.NET Core的web应用程序,本文我们所关心的只有2个:
    1、Model
    2、DB Table

    当下:

    Model

    最后一个为导航属性,无视。

    Table

    现在我们要在Model/Student.cs 加一个属性

       public string NewColForTest { get; set; }
    

    更改后

    对应的Table,我们希望变成如下

    如何操作呢?

    办法有很多,本文介绍由EF Core提供的一种迁移。

    优点

    • 不需要去手动操作数据库
    • 不会影响现有db data(也就是不是重建db)
    • 可追溯更改内容,即版本控制

    开始动手

    前期准备

    建一个ASP.NET Core web Application,用EF Core连接好数据库,建好Student.cs

    编辑*.csproj 文件,添加highlight内容

    cmd 定位到项目根目录(即Startup.cs所在目录)

    dotnet ef migrations add InitialCreate

    将初始化EF Core用于迁移的文件。InitialCreate是其中一个迁移记录的版本文件名,暂不关心。

    现在你的项目中将多出:

    【SchoolContext】ModelSnapshot里面记录了要生成db的内容。

    20180513071210_【InitialCreate】记录了此次更新(同上个版本)的部分,由于我们是第一次初始化,所以里面记录了全部表结构内容。

    【SchoolContext】ModelSnapshot:

    partial class SchoolContextModelSnapshot : ModelSnapshot
        {
            protected override void BuildModel(ModelBuilder modelBuilder)
            { 
                modelBuilder
                    .HasAnnotation("ProductVersion", "2.0.2-rtm-10011")
                    .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
    
               ...
    
                modelBuilder.Entity("ContosoUniversity.Models.Student", b =>
                    {
                        b.Property<int>("ID")
                            .ValueGeneratedOnAdd();
    
                        b.Property<DateTime>("EnrollmentDate");
    
                        b.Property<string>("FirstMidName");
    
                        b.Property<string>("LastName");
    
                        b.Property<string>("NewColForTest");
    
                        b.HasKey("ID");
    
                        b.ToTable("Student");
                    });
    
                ...
            }
        }
    

    20180513071210_【InitialCreate】:

    public partial class InitialCreate : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {
                ...
    
                migrationBuilder.CreateTable(
                    name: "Student",
                    columns: table => new
                    {
                        ID = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        EnrollmentDate = table.Column<DateTime>(nullable: false),
                        FirstMidName = table.Column<string>(nullable: true),
                        LastName = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Student", x => x.ID);
                    });
    
               ... 
            }
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                ...
                migrationBuilder.DropTable(
                    name: "Student");
            }
        }
    

    回到cmd 定位到项目根目录

    dotnet ef database update

    EF Core将为我们跟db同步

    现在我们的db应该跟Model是一致的(多余的细节,这里就不赘述了)

    做到这里,我们应该清楚EF Core是通过生成/Migrations Folder的内容来实现同步db。

    此时还会新生成一个表用于版本记录

    EF Core 使用 __MigrationsHistory 表查看是否需要运行任何迁移。 如果 DB 已是最新,则无需运行迁移。

    Now

    更改Student.cs

    添加新属性NewColForTest

    按照我们的猜测,要同步更新db,应该就是更改/Migrations Folder里的内容。把该属性对应的添加上去,然后执行

    dotnet ef database update

    即可实现同步更新(迁移)。

    现在这里可以手动更改/Migrations Folder里的两个文件,然后执行cmd。

    那么可以不手动吗?

    可以,先执行命令,生成一个新的差异版本Migration,我们命名为UpdateStudent

    dotnet ef migrations add UpdateStudent

    结果

    点开文件

    只有差异内容。

     public partial class UpdateStudent : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.AddColumn<string>(
                    name: "NewColForTest",
                    table: "Student",
                    nullable: true);
            }
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.DropColumn(
                    name: "NewColForTest",
                    table: "Student");
            }
        }
    

    最后执行

    dotnet ef database update

    查看我们的db

    原有的数据也仍在。完成。

    注意:如果命令报错,可以检查是否把iis express退出。

    总结

    我觉得很大一个亮点是每次更新都生成一个追踪版本,某些情况下,省去了单独维护sql 脚本的工作。

    与EF Code First比较,运行的更加“透明”,让我们更直接的知道发生了什么,黑魔法的感觉少了很多。Code First更新在配置完成下只需要运行F5,即DB 同步成功,让人感觉不是那么“亲近”。

    认识较浅,请指教。

    Thanks All.

    欢迎讨论~
    感谢阅读~

    个人公众号:

    原文:http://www.cnblogs.com/joeymary/p/9032825.html

  • 相关阅读:
    代理类和装饰类的区别
    spring mvc 处理映射的几种方式
    如何深入浅出的理解跳转方式:重定向和请求转发
    springMVC拦截配置
    ※版本管理※=>☆SVN工具=>※解决地域麻烦※№→搭建自己的网络SVN (SourceForge 免费) [转]
    权力社会? 金钱社会? 透过现象看本质-让权力和金钱的力量沿着制度的河道流淌,才是社会稳定的基石
    自己封装的CMusic类 【转】
    VC++中MCI播放音频文件 【转】
    DevExpress.XtraGrid 【转】
    C# Process.Start()方法详解 [转]
  • 原文地址:https://www.cnblogs.com/joeymary/p/9032825.html
Copyright © 2011-2022 走看看