EF6 學習筆記(五):數據庫遷移及部署


EF6學習筆記總目錄:ASP.NET MVC5 及 EF6 學習筆記 - (目錄整理)

原文地址:Code First Migrations and Deployment

原文主要講兩部分:開發環境下數據庫遷移到其他數據庫服務器;以及在Azure上如何部署應用;

遷移數據庫

原文前面講一堆內容,主要就是說數據庫在開發過程中,如果數據模型經常需要調整,那么數據庫每次都刪除重建有點不太現實;尤其是對於已部署的正式環境,需要的僅僅是數據庫升級,而不可能直接Drop掉,再重新Create.

所以,需要啟用EF的數據遷移功能。

原文為了演示效果更好,就直接演示了遷移升級到一個全新的數據庫中:

第1步:把Web.config文件中 entityFramework節點下 contexts注釋掉:

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

第2步:數據庫連接字符串中,數據庫名改個名字,比如EFTest2

<connectionStrings>
    <add name="SchoolContext" connectionString="Data Source=(localdb)\ProjectsV13;Initial Catalog=EFTest2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;" providerName="System.Data.SqlClient" />
  </connectionStrings>

第3步:打開PM控制台:

第4步: 先執行 enable-migrations , 會創建一個Migrations子目錄,並多出一個Configuration.cs文件;

再執行 add-migration InitialCreate , 會在Migrations子目錄創建一個帶時間戳的 xxxxxxxxxx_InitialCreate文件;

第5步,在Configuration.cs文件 有個Seed方法就是用來初始化數據庫的時候放入的種子數據; 可以如以下方式加入數據:

在這個要注意,Seed方法在后面執行update-database命令的時候會被執行,而且每次執行update-database命令的時候都會執行;

所以這個地方需要用AddOrUpdate來處理一些種子數據,防止插入重復數據;

另外,注意一些外鍵數據,例如是數據庫自增長的列,則需要前面先保存的數據到數據庫,然后才用ID這屬性值(不然ID是沒數據的)

namespace EFTest.Migrations
{
    using Models;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<EFTest.DAL.SchoolContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(EFTest.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" }
            //    );
            //

            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();
        }
    }
}

帶時間戳的 xxxxxxxxxx_InitialCreate文件本次不需要自己調整,主要包含了Up和Down 方法;

Up用來升級數據庫;Down用來恢復數據庫;

第6步:在PM控制台輸入 update-database 進行數據升級(本次是新建一個新數據庫EFTest2 並新建表,並插入種子數據)

 

部署至 Azure

后面部分原文采用的是國際版的Azure,並且是經典管理頁面,后面本人將采用國內世紀互聯版Azure以及新的資源組管理頁面來測試部署應用;

前提條件:需要有世紀互聯運營的中國區Azure訂閱賬號!

www.portal.azure.cn 用訂閱賬號登錄。

步驟1:先新建一個資源組用來進行綜合管理項目下屬的Azure資源(如 App Service , SQL DB, 或者以后Blob 存儲等)

步驟2:建SQL Server 數據庫,本次先用SQL Server 測試;(Azure也支持MySQL)

 

先輸入數據庫名稱,選擇第1步創建好的資源組;點擊配置Server,在右頁點擊新建一個Server (如果已經有DB Server ,可以直接選擇,一個Server上可以多個DB實例)

如果是新建的Server ,需要輸入Server Name ,以及設置訪問的賬號及密碼;選擇區域,人在上海,所以選擇東區;

默認的數據庫規格有點高,測試就用最小的規格就可以。。。選擇Price Tier 改為 5DTU 2GB

點擊Create后,等創建結束即可;可以點擊刷新按鈕看下:

步驟3:數據庫新建后,就可以做次數據庫遷移;

在做數據庫遷移之前,需要設置Azure的數據庫可以被本地的IP地址訪問到:

點擊選中SQL 數據庫,在Overview的右頁點擊 Set Server firewall

不需要自己去查自己的外網IP地址是多少,已經自動幫你列好,只要點上面的Add client IP按鈕即可:

千萬記得點 Save

獲取連接字符串:

把拷貝的數據庫連接字符串粘貼到應用的Web.Config

(請把賬號和密碼填進去。。。。。不要忘記了)

然后直接在PMC輸入 update-database

步驟4:新建App Service

選擇Web App:

一堆廢話就不看了,點創建按鈕:

輸入AppName,選擇資源組,點擊App Service plan/Location 按鈕,在右頁點擊Create New:

輸入App Service Plan Name ,選擇區域,點擊Prcing tier ,選擇B1 Basic (最便宜,測試嘛,能省則省)

選好后,點創建按鈕:

一般幾分鍾后,就能創建成功;

步驟5: 設置VS2017可以訪問中國版Azure :

參考:

https://docs.azure.cn/zh-cn/articles/others/aog-portal-management-qa-vs2017-login

步驟6:發布應用

VS2017登錄成功后,可以在Server Explorer里看到自己的Azure訂閱,以及訂閱下面的所有資源;

郵件點擊項目發布后,選擇發布到MS Azure App Service , 並點選Select Existing ,然后點Publish按鈕:

選擇准備發布的App Serivce ,然后點 Ok按鈕:

Output窗口輸出結果:

成功后,會自動啟動瀏覽器打開網頁:

 

 


免責聲明!

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



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