EF CodeFirst系列(8)---添加初始化數據和數據庫遷移策略

1.添加初始化數據(Seed)

  咱們能夠在初始化數據庫的過程當中給數據庫添加一些數據。爲了實現初始化數據(seed data)咱們必須建立一個自定義的數據庫初始化器(DB initializer),並重寫其中的Seed方法。html

  下邊的栗子展現在School數據庫中給Standard表添加默認的數據:數據庫

第一步:建立自定義初始化器ide

//繼承三種內置的初始化器中的DropCreateDatabaseAlways
public class SchoolDBInitializer : DropCreateDatabaseAlways<SchoolDBContext>
{
    protected override void Seed(SchoolDBContext context)
    {
        IList<Standard> defaultStandards = new List<Standard>();

        defaultStandards.Add(new Standard() { StandardName = "Standard 1", Description = "First Standard" });
        defaultStandards.Add(new Standard() { StandardName = "Standard 2", Description = "Second Standard" });
        defaultStandards.Add(new Standard() { StandardName = "Standard 3", Description = "Third Standard" });

        context.Standards.AddRange(defaultStandards);
     //初始化數據
        base.Seed(context);
    }
}

第二步.將自定義的數據庫初始化器添加到context中工具

public class SchoolContext: DbContext 
{
    public SchoolContext(): base("SchoolDB") 
    {
        Database.SetInitializer(new SchoolDBInitializer());
    }
    
    public DbSet<Student> Students { get; set; }
    public DbSet<Standard> Standards { get; set; }
}

2.數據庫遷移策略

  前邊咱們已經知道了EF中的數據庫遷移策略(CreateDatabaseIfNotExists,DropCreateDatabaseIfModelChanges, and DropCreateDatabaseAlways.),可是由於這些策略都是刪除舊的數據庫而後建立一個新的數據庫,因此使用這些策略會形成數據庫中的數據(不是seed data的數據)、存儲過程、觸發器等內容丟失ui

  針對上邊的問題,EF提供了一個新的數據庫初始化器 MigrateDatabaseToLastestVersion,這個工具在實體模型改變時自動幫咱們更新數據庫,且不會形成數據丟失。spa

下邊介紹兩種更新數據庫的方法:設計

1.自動遷移

第一步:3d

在程序包管理器控制檯輸入code

enable-migrations –EnableAutomaticMigration:$true

執行成功後,EFAp建立了一個繼承自DbMigrationConfiguration類的Configuration類,以下htm

    internal sealed class Configuration : DbMigrationsConfiguration<EF6Demo.SchoolContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;//自動遷移爲true
            AutomaticMigrationDataLossAllowed = true;//容許數據丟失,默認生成時沒有這一項(不添加這一項時,只在添加/刪除實體類時自動生成,若是咱們刪除了實體類的一個屬性就會拋出異常)
            ContextKey = "EF6Demo.SchoolContext";
        }

        protected override void Seed(EF6Demo.SchoolContext 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.
        }
    }

 

第二步:

把數據庫初始化器添加到配置中,context代碼以下:

    public class SchoolContext : DbContext
    {
        public SchoolContext() {
            //添加MigrateDatabaseToLatestVersion數據庫初始化器
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>());
        }
        public virtual DbSet<Student> Students { get; set; }
        public virtual DbSet<Standard> Standards { get; set; }
        
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }

完成上邊兩步,當咱們修改實體類時運行程序就會自動更新數據庫。

2.使用代碼遷移

   上邊咱們瞭解了經過自動遷移來更新數據庫,這裏介紹經過代碼更新數據庫的方法。經過代碼更新數據庫的功能更強大,如咱們能夠給數據庫的列添加默認值,添加計算列等。

  使用代碼遷移,咱們在程序包控制檯執行如下過程:

1.Enable-Migrations [-f]

  這條命令會生成一個Configuration文件,當配置文件存在時可經過-f後綴強制覆蓋舊文件。執行成功後添加了Migrations文件夾,文件夾中包含一個Configuration配置類,以下:

Configuration配置類代碼以下:

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

        protected override void Seed(EF6Demo.SchoolContext 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.
        }
    }

2.Add-Migration [MigName]

  首先在context類中指定初始化器是MigrateDatabaseToLatestVersion初始化器,以下:

   public class SchoolContext : DbContext
    {
        public SchoolContext() {
            //添加MigrateDatabaseToLatestVersion數據庫初始化器
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>());
  
        }
        public virtual DbSet<Student> Students { get; set; }
        public virtual DbSet<Standard> Standards { get; set; }
        
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }

在包管理器控制檯執行:

 Add-Migration FirstInit

這會在Migration文件夾中生成一個<stamp>_name的遷移類:

 遷移類的代碼以下:

    public partial class FirstInit : DbMigration
    {
        //升級
        public override void Up()
        {
            CreateTable(
                "dbo.Standards",
                c => new
                    {
                        StandardId = c.Int(nullable: false, identity: true),
                        StandardName = c.String(),
                    })
                .PrimaryKey(t => t.StandardId);
            
            CreateTable(
                "dbo.Students",
                c => new
                    {
                        StudentId = c.Int(nullable: false, identity: true),
                        StudentName = c.String(),
                        Standard_StandardId = c.Int(),
                    })
                .PrimaryKey(t => t.StudentId)
                .ForeignKey("dbo.Standards", t => t.Standard_StandardId)
                .Index(t => t.Standard_StandardId);
            
        }
        //降級
        public override void Down()
        {
            DropForeignKey("dbo.Students", "Standard_StandardId", "dbo.Standards");
            DropIndex("dbo.Students", new[] { "Standard_StandardId" });
            DropTable("dbo.Students");
            DropTable("dbo.Standards");
        }
    }

咱們能夠看到遷移類中包含Up()和Down()方法,分別用於數據庫的更新和回退。

3.Update-Database 

① updata-database [-verbose]

  在程序包控制檯中執行這條命令時,會執行Add-Migration命令建立的最新的遷移文件,並更新數據庫

執行完上邊三步數據庫就生成了,之後當咱們修改實體類時,執行Add-Migration [MigName]後再執行Update-Database [-verbose],就可方便地根據模型的變化更新數據庫。

② update-database -TargetMigration:xxx

若是咱們想回退到某一個版本時執行:

update-database -TargetMigration:FirstInit//數據庫回退到第一次的版本

 3.codeFirst中的設計器

  咱們知道codeFirst模式中不支持設計器,設計器對咱們理解實體間關係仍是頗有用的,怎麼在code-first中使用設計器呢?Visual Studio Marketplace.點擊連接下載工具,安裝便可,安裝完成重啓VS,在context上點擊右鍵,而後會有一個Entity Framework選項,以下圖:

點擊ViewEntity Data Model選項就能夠自動生成設計器,以下:

這個工具十分好用,同時也支持生成Model XML和DDL SQL推薦使用。

相關文章
相關標籤/搜索