Entity Framework Code First迁移基本面拾遗

 

项目中用到了EF Code First和迁移,但发现有些方面似懂非懂。比如:如何在迁移文件中控制迁移过程?如果在迁移文件中执行SQL语句?如何使用Update-Database的其它参数?数据库在生产环境的时候如何迁移?于是就有了下面的这些体验:


enable-migration

第一次生成数据库时使用。

→ enable-migration
→ 在类库下多了Migrations文件夹,包含Configuration.cs和每次的迁移记录文件

每次的迁移文件大致是:

public partial class InitialCreae : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "Aliases",
            c => new 
                {
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(nullable: false),
                    UserName = c.String(maxLength:30),
                    Email = c.String(),
                    Bio = c.String(),
                    CreateDate = c.DateTime(nullable: false)
                }
        )
        .PrimaryKey(t => t.Id);
        
        CreateTable(
            "Tweets",
            c => new 
                {
                    Id = c.Int(nullable: false, identity:true),
                    CreateDate = c.DateTime(nullable: false),
                    AliasId = c.Int(nullable:false)
                }
        )
        .PrimaryKey(t => t.Id)
        .ForeignKey("Aliases", t => t.AliasId, cascadeDelete: true)
        .Index(t => t.AliasId);
    }
    
    public override Down()
    {
        DropIndex("Tweets", new[]{"AliasId"});
        DropForeignKey("Tweets", "AliasId", "Aliases");
        DropTable("Tweets");
        DropTable("Aliases");
    }
}

 

迁移的配置文件大致是:

internal sealed class Configuration : DbMigrationsConfiguration<TweeterContext>
{
    public Configuration()
    {
        AutomatecMigrationsEnabled = false;
    }
    
    protected override void Seed(TwitterContext context)
    {
    
    }
}

 

数据库初始化

Database.SetInitializer(new MigrateDatabaseToLastesVerstion<TwitterContext, Configuration>());

自动或手动迁移设置

 

public class Configuration : : DbMigrationsConfiguration<TweeterContext>
{
    public Configuration()
    {
        //如果手动迁移,设置成false
        AutomaticMigrationsEnabled = true;
        
        //即使列中有数据,这个列也可以被删除,删除的时候只是少了该列的数据
        AutomaticMigrationDataLossAllowd = true;
    }
}

 

Add-Migration

每次迁移保存在本地。

配置文件大致如下:

public class Configuration : DbMigrationsConfiguration<TwitterContext>
{
    public Configuraiton()
    {
        AutomatcMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = true;
    }
    
    protected override void Seed(TwitterContext context)
    {
    
    }
}

 

→ 比如增加一个列

→ 运行: Add-Migration somename

→ 迁移文件大致是

public partial class AddSomeColumnToSomeTable : DbMigration
{
    public override void up()
    {
        AddColumn("sometable", "somecolumn", c => c.String());
    }
    
    public override void Down()
    {
        DropColumn("sometable", "somecolumn");
    }
}

 

Update-Database

更新数据库,执行没有被执行的迁移文件。

→ 执行:update-database -verbose

verbose表示显示更新明细,会显示执行了哪些迁移,执行了哪些SQL语句。

→ 其它参数

TargetMigration
Script & SourceMigration:创建SQL语句
Force:允许数据丢失
ProjectName:DbMigrationsConfiguraiton所在的类库
ConfigurationTypeName:DbMigrationsConfiguration的继承类
SartUpProjectName:连接字符串所在的类库
ConnectionString & ConnectionProviderName:明确连接字符串或provider

或者通过:get-help update-database -detailed, 了解更多。

回滚

Update-Database -TargetMigration:"SomeMigrationName" -verbose

在迁移文件中自定义一些迁移动作,控制迁移过程

所有的迁移文件继承自DbMigration这个类,该类提供了很多方法供我们控制迁移过程。

→ 比如让增加的类有一个默认值

public partial class AddSomeColumn : DbMigration
{
    public override void Up()
    {
        AddColumn("sometable", "somecolumn", c => c.String(defaultValue: "sth"));
    }
    
    public override void Down()
    {
        DropColumn("sometable", "somecolumn");
    }
}

 

执行SQL语句

比如,现有数据的某些列为NULL,如果想给这些行的该列附上值,该如何做呢?

→ 改变领域模型
→ 执行:Add-Migration somename
→ 在迁移文件中执行SQL语句

 

public partial class AddSome : DbMigration
{
    public override void Up()
    {
        AddColumn("table", "column", c => c.String(maxLength:10));
        Sql("Update table set column='sth'");
    }
    
    public override void Down()
    {
        DropColumn("table", "column");
    }
}

 

→ Update-Database -verbose

数据库的种子数据

 

public class Configuration : DbMigrationsConfiguraiton<TwitterCotext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigraitoinDataLossAllowed = true;
    }
    
    protected override void Seed(TwitterContext context)
    {
        context.Aliases.AddOrUpdate(a => a.Name, new Alias{}, new ALias())
    }
}

 

对生产环境下的数据库作迁移

→ 执行:udb -script -verbose
→ 弹出一个可以编写sql语句的窗口,此时没有与数据库连接

alter table sometable add column nvarchar(max)

insert into _MigrationHistory(MigrationId,CreatedOn, Model, ProductVersion) values(...)

→ 执行:udb -verbose

此时与数据库连接,执行语句

→ 如果想从某个一个迁移开始

udb -sourcemigration:"somename" -script

→ 执行: udb -verbose

关闭种子数据

Database.SetIntializer<SomeContext>(null);

 

posted @ 2016-03-17 00:47  Darren Ji  阅读(835)  评论(0编辑  收藏  举报

我的公众号:新语新世界,欢迎关注。