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


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

  我們可以在初始化數據庫的過程中給數據庫添加一些數據。為了實現初始化數據(seed data)我們必須創建一個自定義的數據庫初始化器(DB initializer),並重寫其中的Seed方法。

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

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

//繼承三種內置的初始化器中的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的數據)、存儲過程、觸發器等內容丟失

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

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

1.自動遷移

第一步:

在程序包管理器控制台輸入

enable-migrations –EnableAutomaticMigration:$true

執行成功后,EFAp創建了一個繼承自DbMigrationConfiguration類的Configuration類,如下

    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推薦使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM