何为EF代码迁移

参考
- SqlLocalDB 实用工具

在开始测试EF代码迁移之前,先来了解下LocalDB。
我们知道微软有一个SQL Server的免费版本SQL Server Express,它是作为学习以及构建桌面或小型服务器应用的入门级的免费数据库。但是作为编程人员,还是觉得体积过大。所以微软为开发者量身定制了一款专门用于编程开发的小数据库SQL Server Express LocalDB(实际上就是从SQL Server Express中抽离出来的)。
如果采用Visual Studio开发,那么恭喜你Visual Studio从2012版本开始就自带了LocalDB。我当前机器在安装 VS2013的时候默认安装了 LocalDB。
开启当前数据库服务

## vs2013 自带的的localdb版本为 v11.0, vs2017的版本为 v13.0##
$ sqllocaldb start v11.0

## 查看命令帮助 ##
$ sqllocaldb -?

## 创建数据库实例 ##
$ sqllocaldb create ef_test

##查看当前实例列表 ##
$ sqllocaldb info

创建控制台应用

打开VS2013,创建一个控制台应用,当前采用的.net 版本为 v4.5.2

安装nuget引用

Install-Package EntityFramework

当前App.config 默认是这样的

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

创建 Blog.cs 和 DbContext 的派生类 BlogContext.cs

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
}
public class BlogContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
}

更改 Program.cs 以调用

static void Main(string[] args)
{
    using (var db = new BlogContext())
    {
        db.Blogs.Add(new Blog { Name = "Another Blog" });
        db.SaveChanges();

        foreach (var blog in db.Blogs)
        {
            Console.WriteLine(blog.Name);
        }
    }

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
}

第一次运行程序就通过了,之前的 App.config 中并没有填写任何的连接字符串,数据保存在哪个数据库实例,哪个数据库中,还不是很清楚。
仔细查看 App.config 中的节点 defaultConnectionFactory中的参数mssqllocaldb应该是 localdb中的实例名称。用 navicat 打开数据库看看

连接数据库

查看数据库

表Blogs根据业务类生成的库表,数据库字段和类的属性是一一对应的。


Blogs

__MigrationHistory


__MigrationHistory

MigrationId: 就是在Add-Migration指令中指定的<版本名>,EF会自动在前面加上时间戳
ContextKey: 主要作用是对Model进行分组,这样不同项目的Model可以在同一个DB中互不干扰
Model:EF会基于DBContext中包含的所有Entity Model生成字节数组,核心代码如下所示
ProductVersion:生成这个Migration的EF的版本号

业务类属性有变化怎么办

Blog类多增加了一个属性 Memo

public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        //新增加一个字段
        public string Memo { get; set; }

    }

异常信息

提示The model backing the 'BlogContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

刚刚在【程序包管理器控制台】中安装EF的时候最后有一段话:

PM> Install-Package EntityFramework
正在安装“EntityFramework 6.2.0”。
您正在从 Microsoft 下载 EntityFramework,有关此程序包的许可协议在 http://go.microsoft.com/fwlink/?LinkID=262998 上提供。请检查此程序包是否有其他依赖项,这些依赖项可能带有各自的许可协议。您若使用程序包及依赖项,即构成您接受其许可协议。如果您不接受这些许可协议,请从您的设备中删除相关组件。
已成功安装“EntityFramework 6.2.0”。
正在将“EntityFramework 6.2.0”添加到 ConsoleApplication1_EF_TEST。
已成功将“EntityFramework 6.2.0”添加到 ConsoleApplication1_EF_TEST。

Type 'get-help EntityFramework' to see all available Entity Framework commands.

接下来再看看 get-help EntityFramework 能获得什么帮助

PM> get-help EntityFramework
TOPIC
    about_EntityFramework

SHORT DESCRIPTION
    Provides information about Entity Framework commands.

LONG DESCRIPTION
    This topic describes the Entity Framework commands. Entity Framework is
    Microsoft's recommended data access technology for new applications.

    The following Entity Framework cmdlets are used with Entity Framework
    Migrations.

        Cmdlet              Description
        -----------------   ---------------------------------------------------
        Enable-Migrations   Enables Code First Migrations in a project.

        Add-Migration       Scaffolds a migration script for any pending model
                            changes.

        Update-Database     Applies any pending migrations to the database.

        Get-Migrations      Displays the migrations that have been applied to
                            the target database.

    The following Entity Framework cmdlets are used by NuGet packages that
    install Entity Framework providers. These commands are not usually used as
    part of normal application development.

        Cmdlet                          Description
        ------------------------------  ---------------------------------------
        Add-EFProvider                  Adds or updates an Entity Framework
                                        provider entry in the project config
                                        file.

        Add-EFDefaultConnectionFactory  Adds or updates an Entity Framework
                                        default connection factory in the
                                        project config file.

        Initialize-EFConfiguration      Initializes the Entity Framework
                                        section in the project config file and
                                        sets defaults.

SEE ALSO
    Enable-Migrations
    Add-Migration
    Update-Database
    Get-Migrations

Enable-Migrations | Enables Code First Migrations in a project.(启用代码迁移)

上面这个命令应该可以试试

PM> Enable-Migrations
Checking if the context targets an existing database...
Detected database created with a database initializer. Scaffolded migration '201903150554139_InitialCreate' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter.
Code First Migrations enabled for project ConsoleApplication1_EF_TEST.

然后检查下 库表Blogs ,没啥变化。
检查下项目,增加了一个文件夹 Migrations,包含两个文件201903150554139_InitialCreate.cs

namespace ConsoleApplication1_EF_TEST.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class InitialCreate : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Blogs",
                c => new
                    {
                        BlogId = c.Int(nullable: false, identity: true),
                        Name = c.String(),
                    })
                .PrimaryKey(t => t.BlogId);
            
        }
        
        public override void Down()
        {
            DropTable("dbo.Blogs");
        }
    }
}

Configuration.cs

namespace ConsoleApplication1_EF_TEST.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<ConsoleApplication1_EF_TEST.BlogContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            ContextKey = "ConsoleApplication1_EF_TEST.BlogContext";
        }

        protected override void Seed(ConsoleApplication1_EF_TEST.BlogContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data.
        }
    }
}

Add-Migration | Scaffolds a migration script for any pending model
changes.(为任何挂起的模型更改提供迁移脚本。)

第一次执行的 Enable-Migrations 是做准备,这里执行Add-Migration 是开始准备给 Blogs表增加字段的脚本了。

#addBlogMemo 是我们给的改动命名

PM> Add-Migration addBlogMemo
Scaffolding migration 'addBlogMemo'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration addBlogMemo' again.

文件夹 Migrations中又生成了一个新文件:201903150640019_addBlogMemo.cs

namespace ConsoleApplication1_EF_TEST.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class addBlogMemo : DbMigration
    {
        public override void Up()
        {
            AddColumn("dbo.Blogs", "Memo", c => c.String());
        }
        
        public override void Down()
        {
            DropColumn("dbo.Blogs", "Memo");
        }
    }
}

此时只是提供了脚本,并没有更改数据库

Update-Database | Applies any pending migrations to the database..(将任何挂起的迁移应用到数据库。)

PM> Update-Database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201903150640019_addBlogMemo].
Applying explicit migration: 201903150640019_addBlogMemo.
Running Seed method.

执行Update-Database后,Blogs表就更新了

Blogs表增加了Memo字段

__MigrationHistory 表也响应的增加了一条记录

__MigrationHistory增加了一条记录

代码迁移完成!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容