本教學系列將示範如何透過 Visual Studio 2012 或 Visual Studio 2010,將 ASP.NET 網頁應用程式部署(發佈)至 Azure App Service Web Apps 或第三方主機供應商。 有關本系列的資訊,請參閱 本系列的第一個教學。
概觀
這個教學說明如何讓專案準備好進行資料庫部署。 應用程式兩個資料庫中的資料庫結構及部分(非全部)資料必須部署到測試、預備及生產環境。
通常,當你開發應用程式時,你會把測試資料輸入資料庫,而這些資料你不想部署到現場。 不過,你可能也有一些想要部署的生產數據。 在這個教學中,你將設定 Contoso 大學專案並準備 SQL 腳本,確保部署時包含正確的資料。
提醒:如果你在教學過程中出現錯誤訊息或某些功能無法運作,請務必查看 故障排除頁面。
SQL Server Express LocalDB (本地資料庫)
範例應用程式使用 SQL Server Express LocalDB。 SQL Server Express 是 SQL Server 的免費版本。 它在開發過程中常被使用,因為它基於與完整版 SQL Server 相同的資料庫引擎。 你可以用 SQL Server Express 測試,並確信應用程式在生產環境中行為相同,只有少數例外,因為不同版本的 SQL Server 功能有所不同。
LocalDB 是 SQL Server Express 的一種特殊執行模式,讓你能以 .mdf 檔案的形式處理資料庫。 一般而言,LocalDB 資料庫檔案會保留在 Web 專案的 App_Data 資料夾。 SQL Server Express 中的使用者執行個體功能也允許您使用 .mdf 文件,但使用者執行個體功能已棄用;因此,建議使用 LocalDB 來處理 .mdf 檔案。
SQL Server Express 通常不會用於生產 Web 應用程式。 特別不建議將LocalDB用於生產環境與Web應用程式,因為它不是設計來搭配IIS使用。
在 Visual Studio 2012 中,LocalDB 預設是隨 Visual Studio 安裝的。 在 Visual Studio 2010 及更早版本中,Visual Studio 預設安裝了 SQL Server Express(不含 LocalDB);這也是為什麼你在 這系列第一個教學中,將它作為前置條件之一安裝。
欲了解更多關於 SQL Server 版本(包括 LocalDB)的資訊,請參閱以下資源 《與 SQL Server 資料庫合作》。
實體框架與通用提供者
為了存取資料庫,Contoso University 應用程式需要以下軟體,因為 .NET 框架未包含這些軟體,必須隨應用程式一同部署:
- ASP.NET 通用提供者 (允許 ASP.NET 會員系統使用 Azure SQL 資料庫)
- 實體架構
由於此軟體包含在 NuGet 套件中,專案已設定好,所需的組合檔已隨專案部署。 (連結指向這些套件的最新版本,可能比你為此教學下載的入門專案所安裝的版本更新。)
如果你是部署到第三方主機供應商而非 Azure,務必使用 Entity Framework 5.0 或更新版本。 早期版本的 Code First Migrations 需要完全信任,大多數主機供應商會在中度信任中執行你的應用程式。 欲了解更多關於 Medium Trust 的資訊,請參閱「 部署到 IIS 作為測試環境 」教學。
設定 Code First 遷移以部署應用程式資料庫
Contoso 大學的應用程式資料庫由 Code First 管理,您將透過 Code First 遷移來部署。 關於使用 Code First Migrations 部署資料庫的概覽,請參閱 本系列的第一篇教學。
當你部署應用程式資料庫時,通常不會只是把所有資料都部署到生產環境,因為裡面很多資料可能只是為了測試目的。 例如,考試資料庫中的學生姓名是虛構的。 另一方面,你通常無法只部署資料庫結構,裡面完全沒有資料。 你的測試資料庫中有些資料可能是真實資料,必須在使用者開始使用應用程式時就已經存在。 例如,你的資料庫可能有一個表格,裡面有有效的成績值或真實系所名稱。
為了模擬這種常見情境,你會設定一個 Code First Migrations Seed 方法,只將你想讓它留在生產環境的資料插入資料庫。 這個 Seed 方法不應該插入測試資料,因為它會在 Code First 建立資料庫後在生產環境中執行。
在 Migrations 尚未推出之前的 Code First 早期版本中,方法通常會透過 Seed 插入測試資料,因為每次模型變更,資料庫都必須完全刪除並從頭重建。 使用 Code First 遷移時,測試資料會在資料庫變更後保留,因此不必在方法中包含測試資料 Seed 。 你下載的專案使用了將所有資料納入 Seed 初始化器類別的方法。 在這個教學中,你會停用那個初始化器類別並啟用遷移。 接著你會在 Migrations 設定類別中更新 Seed 方法,只插入你想插入的生產環境資料。
下圖說明應用程式資料庫的架構:
在這些教學中,你會假設 Student and Enrollment 表格在網站剛部署時應該是空的。 其他資料表則包含應用程式上線時必須預先載入的資料。
停用初始化器
由於您將使用 Code First 遷移,因此不必使用 DropCreateDatabaseIfModelChanges Code First 初始化工具。 此初始化器的程式碼位於 ContosoUniversity.DAL 專案的 SchoolInitializer.cs 檔案中。
appSettings 檔案元素中的一個設定會使該應用程式首次嘗試存取資料庫時執行此初始化器:
<appSettings>
<add key="Environment" value="Dev" />
<add key="DatabaseInitializerForType ContosoUniversity.DAL.SchoolContext, ContosoUniversity.DAL" value="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity.DAL" />
</appSettings>
打開應用程式 Web.config 檔案,移除或註解 add 指定 Code First 初始化器類別的元素。
appSettings該元素現在看起來如下:
<appSettings>
<add key="Environment" value="Dev" />
</appSettings>
備註
另一種指定初始化器類別的方法是呼叫 Database.SetInitializerApplication_Start 檔案中的方法。 如果你在使用該方法指定初始化器的專案中啟用遷移,請移除該程式碼行。
備註
如果你使用 Visual Studio 2013,請在步驟 2 和 3 之間加入以下步驟:(a) 在 PMC 中輸入「update-package entityframework -version 6.1.1」以取得目前的 EF 版本。 接著 (b) 建立專案,取得建置錯誤清單並修正它們。 刪除已不存在命名空間的 using 語句,然後右鍵點選並點擊「解決」以新增需要的 using 語句,最後將 System.Data.EntityState 的所有出現改為 System.Data.Entity.EntityState。
啟用 Code First 移轉
請確保 ContosoUniversity 專案(不是 ContosoUniversity.DAL)被設定為新創專案。 在 解決方案總管中,右鍵點擊 ContosoUniversity 專案,選擇 「設定為啟動專案」。 Code First Migrations 會在啟動專案中尋找資料庫連接字串。
從 工具 選單中,選擇 NuGet 套件管理器>套件管理器 控制台。
在 套件管理員主控台 視窗頂端,選擇 ContosoUniversity.DAL 作為預設專案,然後在提示
PM>下輸入「enable-migrations」。
(如果出現 enable-migrations 指令無法辨識的錯誤,請輸入 update-package EntityFramework -Reinstall 並重新嘗試。)
此指令會在 ContosoUniversity.DAL 專案中建立一個 Migrations 資料夾,並在該資料夾中放入兩個檔案:一個用於設定遷移的 Configuration.cs 檔案,以及用於建立資料庫的第一個遷移的 InitialCreate.cs 檔案。
你在套件管理器主控台的預設專案下拉選單中選擇了 DAL 專案,因為該
enable-migrations指令必須在包含 Code First 上下文類別的專案中執行。 當該類別在類別函式庫專案中時,Code First Migrations 會尋找該解決方案的啟動專案中的資料庫連接字串。 在 ContosoUniversity 的解決方案中,網頁專案被設定為新創專案。 如果你不想在 Visual Studio 裡指定有連接字串的專案作為啟動專案,可以在 PowerShell 指令中指定啟動專案。 要查看指令語法,請輸入指令get-help enable-migrations。這個指令會
enable-migrations自動生成第一次資料遷移,因為資料庫已經存在。 另一個方法是讓遷移部門建立資料庫。 要做到這點,請在啟用遷移前,使用 Server Explorer 或 SQL Server 物件總管 刪除 ContosoUniversity 資料庫。 啟用遷移後,手動輸入指令「add-migration InitialCreate」來建立第一個遷移。 接著你可以輸入指令「update-database」來建立資料庫。
設定種子方法
在這個教學中,您將透過在 Code First Migrations 類別的Configuration方法中加入Seed程式碼來新增固定資料。 Code First Migrations 在每次遷移後都會呼叫這個 Seed 方法。
由於 Seed 方法會在每次遷移後執行,因此在第一次遷移後,資料表中已經有資料存在。 為了應對這種情況,您可以使用AddOrUpdate方法來更新已插入的列,或者在其尚不存在時進行插入。 這個 AddOrUpdate 方法可能不是你情況的最佳選擇。 更多資訊,請參閱 Julie Lerman 的部落格文章 「小心使用 EF 4.3 AddOrUpdate 方法」。
打開 Configuration.cs 檔案,並用以下程式碼替換方法中的
Seed註解:var instructors = new List<Instructor> { new Instructor { FirstMidName = "Kim", LastName = "Abercrombie", HireDate = DateTime.Parse("1995-03-11"), OfficeAssignment = new OfficeAssignment { Location = "Smith 17" } }, new Instructor { FirstMidName = "Fadi", LastName = "Fakhouri", HireDate = DateTime.Parse("2002-07-06"), OfficeAssignment = new OfficeAssignment { Location = "Gowan 27" } }, new Instructor { FirstMidName = "Roger", LastName = "Harui", HireDate = DateTime.Parse("1998-07-01"), OfficeAssignment = new OfficeAssignment { Location = "Thompson 304" } }, new Instructor { FirstMidName = "Candace", LastName = "Kapoor", HireDate = DateTime.Parse("2001-01-15") }, new Instructor { FirstMidName = "Roger", LastName = "Zheng", HireDate = DateTime.Parse("2004-02-12") } }; instructors.ForEach(s => context.Instructors.AddOrUpdate(i => i.LastName, s)); context.SaveChanges(); var departments = new List<Department> { new Department { Name = "English", Budget = 350000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 1 }, new Department { Name = "Mathematics", Budget = 100000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 2 }, new Department { Name = "Engineering", Budget = 350000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 3 }, new Department { Name = "Economics", Budget = 100000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 4 } }; departments.ForEach(s => context.Departments.AddOrUpdate(d => d.Name, s)); context.SaveChanges(); var courses = new List<Course> { new Course { CourseID = 1050, Title = "Chemistry", Credits = 3, DepartmentID = 3 }, new Course { CourseID = 4022, Title = "Microeconomics", Credits = 3, DepartmentID = 4 }, new Course { CourseID = 4041, Title = "Macroeconomics", Credits = 3, DepartmentID = 4 }, new Course { CourseID = 1045, Title = "Calculus", Credits = 4, DepartmentID = 2 }, new Course { CourseID = 3141, Title = "Trigonometry", Credits = 4, DepartmentID = 2 }, new Course { CourseID = 2021, Title = "Composition", Credits = 3, DepartmentID = 1 }, new Course { CourseID = 2042, Title = "Literature", Credits = 4, DepartmentID = 1 } }; courses.ForEach(s => context.Courses.AddOrUpdate(s)); context.SaveChanges(); courses[0].Instructors.Add(instructors[0]); courses[0].Instructors.Add(instructors[1]); courses[1].Instructors.Add(instructors[2]); courses[2].Instructors.Add(instructors[2]); courses[3].Instructors.Add(instructors[3]); courses[4].Instructors.Add(instructors[3]); courses[5].Instructors.Add(instructors[3]); courses[6].Instructors.Add(instructors[3]); context.SaveChanges();在
List的下方會有紅色波浪線,因為你還沒有為它的命名空間提供using宣告。 右鍵點選其中一個List實例,選擇解決,然後選擇使用 System.Collections.Generic。
透過此選單選項將以下程式碼加入檔案
using開頭附近的語句。using System.Collections.Generic;按 CTRL-SHIFT-B 來建立專案。
該專案現已準備好部署 ContosoUniversity 資料庫。 部署應用程式後,第一次執行並導覽到存取資料庫的頁面時,Code First 會建立資料庫並執行此 Seed 方法。
備註
在方法中加入程式碼 Seed 是將固定資料插入資料庫的眾多方法之一。 另一種方法是在每個遷移類別的 Up 和 Down 方法中加入程式碼。
Up與Down方法包含實作資料庫變更的程式碼。 你會在「 部署資料庫更新 」教學中看到這些範例。
你也可以用這個 Sql 方法寫出執行 SQL 語句的程式碼。 例如,如果你在部門資料表中新增一個預算欄位,並想將所有部門預算初始化為 1,000.00 美元作為遷移的一部分,你可以在遷移方法中加入以下程式碼行:Up
Sql("UPDATE Department SET Budget = 1000");
建立會員資料庫部署腳本
Contoso University 應用程式使用 ASP.NET 會員系統及表單認證來驗證及授權使用者。 更新致謝頁面僅對處於管理員角色的使用者開放。
執行應用程式,點選 課程,然後點 選更新學分。
登入頁面 會出現是因為 更新點數 頁面需要管理員權限。
輸入 admin 作為使用者名稱, devpwd 作為密碼,然後點 選登入。
更新 點數 頁面會出現。
使用者與角色資訊存放於 aspnet-ContosoUniversity 資料庫,該資料庫由 Web.config 檔案中的 DefaultConnection 連接字串指定。
這個資料庫並非由 Entity Framework Code First 管理,因此你無法使用 Migrations 來部署它。 你會使用 dbDacFx 提供者來部署資料庫結構,並設定發佈設定檔執行腳本,將初始資料插入資料庫資料表。
備註
Visual Studio 2013 引入了新的 ASP.NET 會員系統(現稱為 ASP.NET Identity)。 新系統允許您將應用程式與會員資料表同時存放在同一資料庫中,並可使用 Code First Migrations 部署兩者。 範例應用程式使用早期的 ASP.NET 成員系統,該系統無法透過 Code First 遷移部署。 部署此成員資料庫的程序同樣適用於任何需要部署非由 Entity Framework Code First 建立的 SQL Server 資料庫的應用程式情境。
在這裡,你通常也不希望在生產環境中看到和開發時相同的資料。 當你第一次部署一個網站時,通常會排除大部分或全部你建立的測試使用者帳號。 因此,下載的專案有兩個會員資料庫:aspnet-ContosoUniversity.mdf 用於開發用戶,和 aspnet-ContosoUniversity-Prod.mdf 用於生產用戶。 在這個教學中,兩個資料庫的使用者名稱都是相同的: 管理員 和 非管理員。 兩個使用者在開發資料庫中都有 devpwd 密碼,在生產資料庫中使用 prodpwd 。
你會把開發使用者部署到測試環境,而將生產使用者部署到暫存環境和生產環境。 為了做到這點,你會在本教學中建立兩個 SQL 腳本,一個用於開發,一個用於生產,並在後續教學中設定發佈流程以執行這些腳本。
備註
會員資料庫儲存帳號密碼的雜湊值。 為了從一台機器部署帳號到另一台,你必須確保雜湊例程不會在目的伺服器產生與來源電腦不同的雜湊值。 只要不更改預設演算法,使用 ASP.NET 通用提供者時,它們會產生相同的雜湊值。 預設演算法為 HMACSHA256,並在 Web.config 檔案中 machineKey 元素的驗證屬性中指定。
您可以手動建立資料部署腳本,使用 SQL Server Management Studio(SSMS),或使用第三方工具。 接下來的教學會教你如何在 SSMS 中操作,但如果你不想安裝並使用 SSMS,也可以從專案完成版本取得腳本,然後跳到存放在解決方案資料夾的區塊。
要安裝 SSMS,請從 下載中心安裝:Microsoft SQL Server 2012 Express ,點擊 ENU\x64\SQLManagementStudio_x64_ENU.exe 或 ENU\x86\SQLManagementStudio_x86_ENU.exe。 如果你為系統選錯版本,安裝就會失敗,此時你可以嘗試另一個版本。
(請注意,這是 600 MB 的下載檔。安裝可能需要很長時間,且需要重新啟動電腦。)
在 SQL Server 安裝中心的第一頁,點擊 「新 SQL Server 獨立安裝」或「新增功能」到現有安裝,並依照指示操作,接受預設選項。
建立開發資料庫腳本
執行 SSMS。
在 「連接伺服器 」對話框中,輸入 (localdb)\v11.0 作為 伺服器名稱,將 認證 設為 Windows 認證,然後點選 連接。
在 物件總管 視窗中,展開 資料庫,右鍵點選 aspnet-ContosoUniversity,點選 任務,然後點 選產生腳本。
在 「產生並發佈腳本 」對話框中,點選 「設定腳本選項」。
你可以跳過 選擇物件 步驟,因為預設是 腳本處理整個資料庫和所有資料庫物件 ,這才是你想要的。
按一下 [進階] 。
在 進階腳本選項 對話框中,往下滑到 「要編寫資料的類型」,然後在下拉選單中點選 「僅資料 」選項。
將 Script USE DATABASE 更改為 False。 USE 語句不適用於 Azure SQL Database,也不需要在測試環境中部署到 SQL Server Express。
按一下 確定。
在 「產生與發佈腳本 」對話框中, 檔案名稱 框會指定腳本的建立地點。 把你的解決方案資料夾(包含你ContosoUniversity.sln檔案的資料夾)的路徑改成 aspnet-data-dev.sql。
點選 「下一步 」進入 摘要 標籤,再點 「下一頁 」建立腳本。
按一下完成。
建立生產資料庫腳本
因為你還沒用生產資料庫執行專案,所以它還沒綁定到 LocalDB 實例。 因此你需要先附上資料庫。
在 SSMS 物件總管中,右鍵點擊 資料庫 並點擊 附加。
在「附加資料庫」對話框中,點選新增,然後前往App_Data資料夾中的aspnet-ContosoUniversity-Prod.mdf檔案。
按一下 確定。
按照你之前用過的程序來建立製作檔的腳本。 劇本檔名稱 aspnet-data-prod.sql。
總結
兩個資料庫現在都準備好部署,你的解決方案資料夾裡有兩個資料部署腳本。
在以下的教學中,你會設定影響部署的專案屬性,並設定自動的 Web.config 檔案轉換,以確保在已部署的應用程式中相關設定會有所不同。
其他資訊
欲了解更多 NuGet 相關資訊,請參閱 「用 NuGet 管理專案函式庫 」及 「NuGet 文件」。 如果你不想使用 NuGet,你需要學會如何分析 NuGet 套件,以判斷它安裝後的功能。 (例如,它可能會設定 Web.config 轉換、設定 PowerShell 腳本在建置時執行等。)想了解更多 NuGet 的運作方式,請參閱 「建立與發佈套件 與 組態檔」以及「原始碼轉換」。