MVC5+EF6--5 Code First遷移和部署

MVC5+EF6--5 Code First遷移和部署html

近期學習MVC5+EF6,找到了Microsoft的原文,一個很是棒的系列,Getting Started with Entity Framework 6 Code First using MVC 5,網址:http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application。web

    這個系列的原文,能夠上面網址找到。我也從網上找到了相關的譯文。申明,這些譯文,我不是原創,而是從網上找來的,爲避免下次還要網上查詢,現將這些譯文整理放在上面。之後找時間將原文地址附上。數據庫

MVC5+EF6--5 Code First遷移和部署瀏覽器

原文網址:http://www.itnose.net/detail/6105449.html安全

到目前爲止,應用程序一直在本地IIS Express 上運行。爲了讓其餘人可以經過互聯網訪問你的應用程序,你須要將它部署到WEB服務器。服務器

本文章包含如下內容:架構

  • 啓用Code First遷移,遷移功能可以讓你沒必要重建數據庫就能夠更改數據模型並將其部署到生產環境。
  • 將應用程序部署到Windows Azure(可選)

1.啓用Code First遷移mvc

當你在開發應用程序時,你會對數據模型進行頻繁的更改,隨着每一次的更改,數據模型與數據庫架構將再也不一致。你已經對Entity Framework進行了配置讓其在每一次數據模型更改時自動的刪除並從新建立數據庫。當你添加、刪除或更改實體類或更改DbContext類後從新運行應用程序,它會自動的刪除已存在的數據庫並建立一個和當前數據模型相匹配的數據庫,最後使用測試數據初始化。app

在你將應用程序部署到生產環境以前,這種方法會一直保持數據模型和數據庫架構的一致性。當應用程序運行在生產環境並已經存儲了一部分數據時,你不想在數據模型變動(例如添加一個列)時丟掉這部分數據,Code First遷移功能可以經過更新數據庫架構而不是刪除並重建數據庫來很好的解決這個問題。框架

1.禁用初始化程序,註釋或刪除Web.config文件中的contexts元素

<entityFramework>
  <!--<contexts>
    <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
      <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
    </context>
  </contexts>-->
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
      <parameter value="v11.0" />
    </parameters>
  </defaultConnectionFactory>
  <providers>
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>

2.一樣在Web.config文件中,將數據庫鏈接字符串中數據庫的名字修改成ContosoUniversity2

<connectionStrings>
  <add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity2;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>

上面的更改可讓應用程序在作第一次遷移時建立一個新的數據庫,但這不是必須的。

3.依次打開Tools -> Library Package Manager -> Package Manager Console

                       

4.在Package Manager Console中輸入如下命令

enable-migrations
add-migration InitialCreate

 

enable-migrations命令會新建一個Migrations 文件夾,同時文件夾中包含一個Configuration.cs文件,你能夠經過編輯該文件來配置遷移的相關設置。

若是你在上面的步驟中忘記更改數據庫名稱,遷移程序會找到現有的數據庫並自動執行add-migration命令,不過這沒什麼關係,它只是意味着你在部署數據庫以前不會對遷移代碼進行測試,接下來當你執行update-database命令時,數據庫架構不會發生任何變化由於數據庫已經存在。

 

就像以前的初始化程序同樣,Configuration類中包含有一個Seed方法

internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        ContextKey = "ContosoUniversity.DAL.SchoolContext"
    }
 
    protected override void Seed(ContosoUniversity.DAL.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. E.g.
        //
        //    context.People.AddOrUpdate(
        //      p => p.FullName,
        //      new Person { FullName = "Andrew Peters" },
        //      new Person { FullName = "Brice Lambson" },
        //      new Person { FullName = "Rowan Miller" }
        //    );
        //
    }
}


Seed方法的目的是讓你在Code First建立或更新數據庫後能夠插入或更新測試數據,當建立數據庫或更新數據庫架構時該方法被調用。

設置Seed方法

當你爲每次數據模型的更改而刪除和從新建立數據庫時,你須要使用初始化類的Seed方法來插入測試數據,由於在每次數據模型更改後數據庫都會被刪除,同時全部的測試數據也會丟失。若是使用Code First遷移,測試數據是會被保留下來的,因此在Seed方法中包含測試數據一般不是必要的。事實上,若是在使用遷移功能將數據庫部署至生產環境時,你不但願使用Seed方法來插入測試數據,而應該在你須要時再插入相應的測試數據。例如,當你將應用部署到生產環境時,你但願數據庫Deparment表中應該包含department的相關數據。

在本文中,你會使用遷移功能來部署應用程序,可是爲了可以更容易的觀察應用程序是如何無需人工操做而自動插入數據的,咱們會一直使用Seed方法來插入測試數據。

打開Configuration.cs,使用下面的代碼替換;

namespace ContosoUniversity.Migrations
{
    using ContosoUniversity.Models;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
 
    internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            ContextKey = "ContosoUniversity.DAL.SchoolContext"
        }
 
        protected override void Seed(ContosoUniversity.DAL.SchoolContext context)
        {
            var students = new List<Student>
            {
                new Student { FirstMidName = "Carson",   LastName = "Alexander", 
                    EnrollmentDate = DateTime.Parse("2010-09-01") },
                new Student { FirstMidName = "Meredith", LastName = "Alonso",    
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Arturo",   LastName = "Anand",     
                    EnrollmentDate = DateTime.Parse("2013-09-01") },
                new Student { FirstMidName = "Gytis",    LastName = "Barzdukas", 
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Yan",      LastName = "Li",        
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Peggy",    LastName = "Justice",   
                    EnrollmentDate = DateTime.Parse("2011-09-01") },
                new Student { FirstMidName = "Laura",    LastName = "Norman",    
                    EnrollmentDate = DateTime.Parse("2013-09-01") },
                new Student { FirstMidName = "Nino",     LastName = "Olivetto",  
                    EnrollmentDate = DateTime.Parse("2005-08-11") }
            };
            students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
            context.SaveChanges();
 
            var courses = new List<Course>
            {
                new Course {CourseID = 1050, Title = "Chemistry",      Credits = 3, },
                new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3, },
                new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3, },
                new Course {CourseID = 1045, Title = "Calculus",       Credits = 4, },
                new Course {CourseID = 3141, Title = "Trigonometry",   Credits = 4, },
                new Course {CourseID = 2021, Title = "Composition",    Credits = 3, },
                new Course {CourseID = 2042, Title = "Literature",     Credits = 4, }
            };
            courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s));
            context.SaveChanges();
 
            var enrollments = new List<Enrollment>
            {
                new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").ID, 
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
                    Grade = Grade.A 
                },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").ID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, 
                    Grade = Grade.C 
                 },                            
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").ID,
                    CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, 
                    Grade = Grade.B
                 },
                 new Enrollment { 
                     StudentID = students.Single(s => s.LastName == "Alonso").ID,
                    CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment { 
                     StudentID = students.Single(s => s.LastName == "Alonso").ID,
                    CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alonso").ID,
                    CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Anand").ID,
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Anand").ID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                    Grade = Grade.B         
                 },
                new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Barzdukas").ID,
                    CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                    Grade = Grade.B         
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Li").ID,
                    CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                    Grade = Grade.B         
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Justice").ID,
                    CourseID = courses.Single(c => c.Title == "Literature").CourseID,
                    Grade = Grade.B         
                 }
            };
 
            foreach (Enrollment e in enrollments)
            {
                var enrollmentInDataBase = context.Enrollments.Where(
                    s =>
                         s.Student.ID == e.StudentID &&
                         s.Course.CourseID == e.CourseID).SingleOrDefault();
                if (enrollmentInDataBase == null)
                {
                    context.Enrollments.Add(e);
                }
            }
            context.SaveChanges();
        }
    }
}

Seed方法將數據庫上下文對象做爲輸入參數,並使用該對象將實體添加到數據庫,對於每個實體類型,上面的代碼建立了一個新的實體集合並將它們添加到適當的DbSet屬性,最後將更改保存到數據庫。在每一組實體以後調用SaveChanges方法並非必需的,這裏之因此這樣作,是由於在將數據寫入到數據庫時若是發生異常,可讓你更容易的定位問題所在。

插入數據時使用AddOrUpdate方法來執行"upsert"操做,是由於在每次執行update-database命令時Seed方法老是會被調用,一般在每次遷移以後,你不只僅是插入了數據,由於你試圖添加的行可能在建立數據庫後的第一次遷移中已經存在。"upsert"操做能夠在你試圖添加一個已存在的行時防止錯誤的發生,可是它會在你測試應用程序時重置你對數據所作的更改。你也許不但願發生下面的狀況:在某些狀況下你可能但願保留你在測試階段對測試數據所作的更改,在另外一種狀況下,你但願作一個條件插入操做:當且僅當行不存在時才執行插入操做。Seed方法同時使用以上兩種方法。

AddOrUpdate方法的第一個參數指定了一個屬性來檢查行是否已存在。對於提供的測試數據,LastName屬性被用做檢查列的惟一性

context.Students.AddOrUpdate(p => p.LastName, s)

上面的代碼假定LastName具備惟一約束,若是你添加了一個與已有學生的LastName相同的學生,那麼在執行遷移操做時會發生以下異常

Sequence contains more than one element

上面的代碼在建立Enrollment實體時假定Students集合中的實體已經擁有ID值,即便在建立這些集合時沒有爲它們設置該值。

new Enrollment { 
    StudentID = students.Single(s => s.LastName == "Alexander").ID, 
    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
    Grade = Grade.A 
},

這裏可使用ID屬性,由於當你爲學生集合調用SaveChanges方法時ID值會被設置。EF在將實體保存至數據庫時會自動獲取該實體的主鍵值並將該值更新至內存中實體的ID屬性。

將每一個Enrollment實體添加到Enrollments實體集合的代碼並無使用AddOrUpdate方法,它會檢查實體是否已存在,若是不存在,則插入該實體,這種方法將保存在應用程序界面對 enrollment grade所作的更改。該代碼遍歷Enrollment列表中的每一個成員,若是在數據庫中沒有該Enrollment,就將該Enrollment添加至數據庫。當你第一次更新數據庫時,該數據庫是空的,因此每一個enrollment實體都將被添加至數據庫中。

foreach (Enrollment e in enrollments)
{
    var enrollmentInDataBase = context.Enrollments.Where(
        s => s.Student.ID == e.Student.ID &&
             s.Course.CourseID == e.Course.CourseID).SingleOrDefault();
    if (enrollmentInDataBase == null)
    {
        context.Enrollments.Add(e);
    }
}

接下來請編譯項目

執行第一次遷移

當執行add-migration命令時,遷移將生成用來建立數據庫的代碼,該代碼位於Migrations文件夾中的名字爲<timestamp>_InitialCreate.cs的文件中。InitialCreate類中的Up方法會根據實體集合的數據模型來建立數據庫表,Down方法用來刪除它們。

public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Course",
            c => new
                {
                    CourseID = c.Int(nullable: false),
                    Title = c.String(),
                    Credits = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.CourseID);
        
        CreateTable(
            "dbo.Enrollment",
            c => new
                {
                    EnrollmentID = c.Int(nullable: false, identity: true),
                    CourseID = c.Int(nullable: false),
                    StudentID = c.Int(nullable: false),
                    Grade = c.Int(),
                })
            .PrimaryKey(t => t.EnrollmentID)
            .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true)
            .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true)
            .Index(t => t.CourseID)
            .Index(t => t.StudentID);
        
        CreateTable(
            "dbo.Student",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    LastName = c.String(),
                    FirstMidName = c.String(),
                    EnrollmentDate = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.ID);
        
    }
    
    public override void Down()
    {
        DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student");
        DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course");
        DropIndex("dbo.Enrollment", new[] { "StudentID" });
        DropIndex("dbo.Enrollment", new[] { "CourseID" });
        DropTable("dbo.Student");
        DropTable("dbo.Enrollment");
        DropTable("dbo.Course");
    }
}

 

遷移調用Up方法來執行對數據模型所作的更改,當你輸入命令來回滾所作的更新時,遷移將調用Down方法。

當你輸入add-migration InitialCreate命令時將建立一個初始化遷移,InitialCreate參數被用於文件名,固然你也能夠修改成其它你想要的名稱,一般該名稱是一個單詞或者短語,用來指明在遷移中要作的工做,例如,你能夠將下一次遷移命名爲"AddDeparmentTable"。

若是你建立了一個初始化遷移,可是數據庫卻已經存在,那麼生成的用來建立數據庫的代碼是不會運行的,由於數據庫架構和數據模型是一致的。當你將應用程序部署到另外一個數據庫尚不存在的環境中時,該代碼將會運行以建立數據庫,但最好是提早測試一下。這就是爲何要修改鏈接字符串中數據庫的名稱的緣由所在,這樣就能夠建立一個全新的數據庫。

在Package Manager Console窗口輸入如下命令

update-database

 

************************************************************************************************************************

******************************如下內容僅供瞭解,大陸地區暫不能申請測試帳號**********************************

************************************************************************************************************************

2.部署到Windows Azure

到目前爲止應用程序一直運行在本地IIS Express,爲了讓其餘人可以經過互聯網訪問你的應用程序,你須要將它部署到WEB服務器。接下來將教你如何將應用程序部署到Windows Azure。

使用Code First遷移來部署數據庫

當你使用Visual Studio的配置設定來建立發佈配置文件時,你須要勾選名爲Execute Code First Migrations的複選框。此設置能夠在部署過程當中在目標服務器上自動配置應用程序的Web.config文件,以便Code First使用MigrateDatabaseToLatestVersion初始化類。

當部署程序將項目拷貝到目標服務器時,Visual Studio不須要作任何事情。當你運行已經部署的項目,且該項目第一次訪問數據庫時,Code First會檢查數據庫和數據模型是否一致。若是它們不一致,Code First會自動建立數據庫(若是數據庫不存在)或者更新數據庫架構到最新版本(數據庫存在可是模型不一致)。若是應用程序實現了遷移的Seed方法,那麼該方法會在數據被建立或者架構被更新後執行。

Seed方法的做用是插入測試數據。若是你在將項目部署到生成環境,你必須修改Seed方法以便該方法僅在你想將數據插入到生產數據庫時插入數據。舉個例子來講,在當前的數據模型中,你可能但願在開發環境數據庫中擁有真實的課程信息和虛構的學生信息,你能夠在Seed方法中將這些信息添加至開發環境數據庫,並在將項目部署到生產環境時註釋掉添加虛構學生信息的那些代碼。你也能夠僅在Seed方法中添加課程信息,而後在應用程序界面中添加虛構的學生信息到測試數據庫。

註冊Windows Azure帳號

你須要一個Windows Azure帳號,若是你尚未可是卻擁有一個MSDN訂閱,你能夠經過激活MSDN訂閱來得到該帳號。

在Windows Azure中新建一個網站和一個SQL數據庫

Windows Azure網站運行在共享主機中,這意味着該網站運行在虛擬機中。共享主機環境是一種低成本的雲端的環境,若是之後你的網站流量增長時,你能夠將該網站運行在專用虛擬機上來知足須要。

你須要將數據庫部署到Windows Azure SQL數據庫中,SQL數據庫是使用SQL Server技術創建的基於雲的關係型數據庫服務。運行在SQL Server中的工具盒應用一樣也能夠運行在SQL數據庫中。

1.在Windows Azure Management Portal中,點擊左側的Web Sites選項卡,而後點擊New

 

2.點擊CUSTOM CREATE

 

打開New Web Site - Custom Create嚮導

3.在嚮導的New Web Site步驟,在URL文本框中輸入做爲應用程序URL的字符串,完整的URL應該包括你剛纔輸入的加上文本框右側顯示的字符串。下圖中使用了"ConU"做爲URL,但該URL可能已被別人使用,因此你必須填寫一個未被使用過的名稱做爲URL。

 

4.在Region 下拉列表框中選擇一個離你最近的選項,該設置會指定你的應用程序運行在哪一個數據中心。

5.在Database下拉列表框中選擇Create a free 20 MB SQL database選項。

 

6.在 DB CONNECTION STRING NAME中輸入 SchoolContext

 

7.點擊右下角的箭頭圖標,進入Database Settings步驟

8.在Name文本框中輸入ContosoUniversityDB

9.在Server下拉框中選擇New SQL Database server。另外,若是你以前建立了一個服務器,你能夠從下拉框中選擇你所建立的那個服務器。

10.輸入管理員 LOGIN NAME 和PASSWORD,若是你選擇的是New SQL Database server,這裏輸入的用戶名和密碼是事後訪問數據庫時的用戶名和密碼,若是你選擇的是以前建立的服務器,你須要輸入相應認證信息。

11.選擇Region,要和以前選擇的一致

12.點擊右下角的檢查圖標,這表示你已經完成配置過程

 

完成以後會從Management Portal跳轉至Web Sites頁面,Status列會顯示網站正在被建立,過一會以後(一般少於一分鐘),Status列會顯示網站已經被成功建立。

將應用程序部署到Windows Azure

1.打開Visual Studio,在Solution Explorer中右鍵點擊項目,選擇Publish

 

2.在 Publish Web嚮導的Profile選項卡中點擊 Import

 

3.若是以前你沒有在Visual Studio中添加Windows Azure訂閱,請執行接下來的操做,這些操做可讓Visual Studio鏈接至Windows Azure訂閱,以便Import from a Windows Azure web site下的下拉列表框中包含你所建立的網站。

做爲另外一種替代方法,你能夠直接登陸至 Windows Azure而不須要下載一個訂閱文件,若是使用此方法,請在接下來的步驟中點擊 Sign In 而不是Manage subscriptions。這種方法比較簡單,可是本教程寫於2013年9月,當時必須使用下載的訂閱文件才能將Server Explorer鏈接至 Windows Azure SQL Database。

a.在 Import Publish Profile 對話框,點擊 Manage subscriptions

 

b.在Manage Windows Azure Subscriptions對話框,點擊Certificates 選項卡,而後點擊Import.

 

c.在Import Windows Azure Subscriptions對話框,點擊Download subscription file 

 

d.保存.publishsettings文件

 

安全注意事項:publishsettings文件中包含有你的憑證(未編碼)以用來管理Windows Azure訂閱和服務。對此文件來講最安全的作法就是先將其暫時存放在在某一個文件夾中,一旦導入完成就將其刪除。若是被惡意用戶訪問到此文件,他就能夠修改、新建或刪除你的Windows Azure服務。

e.在 Import Windows Azure Subscriptions對話框,點擊Browse並找到 .publishsettings文件

 

f.點擊Import

 

4.關閉 Manage Windows Azure Subscriptions對話框

5.在Import Publish Profile對話框,選擇 Import from a Windows Azure web site,從下拉列表框中選擇你所建立的網站,點擊OK

 

6. 在Connection選項卡,點擊Validate Connection 來確保設置是正確的

 

7.當驗證經過,Validate Connection旁邊會出現一個綠色的對號標記,點擊Next

 

8.打開SchoolContext 下面的Remote connection string下拉框,選擇鏈接字符串

9.選擇Execute Code First Migrations (runs on application start)

 

該設置會使部署程序在目的服務器上自動的配置應用程序的Web.config文件,以便Code First可使用 MigrateDatabaseToLatestVersion初始化類

10.點擊Next

11.在Preview 選項卡,點擊Start Preview

 

該選項卡會顯示將要被拷貝到目的服務器中的文件列表,當你再次部署該應用程序時,此時將會只顯示那些被更改過的文件列表

 

12.點擊Publish,Visual Studio會將文件拷貝至Windows Azure服務器

13.Output窗口會顯示捕獲到的部署動做和已成功完成的部署

 

14.部署成功以後,默認瀏覽器會自動打開該網站,該網站已成功的運行在雲端,點擊Students選項卡

 

此時SchoolContext 數據庫已經在Windows Azure SQL Database中被成功建立,由於你選擇了Execute Code First Migrations (runs on app start)選項。網站的Web.config文件已經被修改以便 MigrateDatabaseToLatestVersion初始化程序在第一次運行時讀寫數據庫(當你點擊Students選項卡時)。

 

在部署過程當中一樣也爲Code First遷移建立了一個查詢字符串(SchoolContext_DatabasePublish)來更新數據庫架構並插入數據。

 

你能夠在你本機的ContosoUniversity\obj\Release\Package\PackageTmp\Web.config中找到Web.config文件部署的版本。

注意:部署的web應用程序並不執行安全檢查,因此任何知道此URL的人均可以修改數據庫中的數據。你能夠經過使用Windows Azure Management Portal 或者 Visual Studio中的 Server Explorer中止運行該網站以防止別人修改你的數據。

 

高級遷移方案

若是你經過運行遷移程序部署了一個數據庫,那麼接下來你將部署一個能運行在多個服務器上的網站,要作到這一點,你須要在多臺服務器上同時運行遷移程序。遷移過程是原子的,若是在兩臺服務器上運行同一個遷移程序,則其中一個會成功,另外一個會失敗(假設操做不能被執行兩次)。在這種狀況下,若是你但願避免出現這個問題,你能夠手動的調用遷移程序並修改你的代碼以確保遷移只發生一次。

Code First初始化程序

在部署程序那一節,能夠看到使用的是MigrateDatabaseToLatestVersion初始化程序,Code First同時也提供了其餘的初始化程序,包括CreateDatabaseIfNotExists(默認)、DropCreateDatabaseIfModelChanges(以前使用的)和DropCreateDatabaseAlways。DropCreateAlways初始化程序對於爲單元測試設置條件是很是有用的。你也能夠編寫你本身的初始化程序,若是你不想一直等直到應用程序可以讀寫數據庫,你能夠顯示的調用初始化程序。

在部署部分中,您看到了正在使用的MigrateDatabaseToLatestVersion初始化。代碼首先還提供了其它的初始化,包括(你以前使用)CreateDatabaseIfNotExists(默認),DropCreateDatabaseIfModelChanges和DropCreateDatabaseAlways。該DropCreateAlways初始化能夠設立條件的單元測試很是有用。您也能夠編寫本身的初始化,您能夠顯式地調用一個初始化,若是你不想一直等到應用程序的讀取或寫入到數據庫中。在本教程中被寫入11月份2013的時候,你只能使用建立和DropCreate初始化啓用遷移以前。實體框架團隊正在努力使這些初始化實用與遷移爲好。

相關文章
相關標籤/搜索