共用方式為


在 ASP.NET MVC 應用程式中,使用 Entity Framework 排序、篩選和分頁 (3/10)

By Tom Dykstra

Contoso University 範例 Web 應用程式示範如何使用 Entity Framework 5 Code First 和 Visual Studio 2012 建立 ASP.NET MVC 4 應用程式。 如需教學課程系列的資訊,請參閱本系列的第一個教學課程

注意

如果您遇到無法解決的問題, 請下載已完成的章節 ,並嘗試重現您的問題。 一般而言,您可以將程式碼與已完成的程式碼進行比較,以找出問題的解決方案。 如需一些常見的錯誤以及如何解決這些問題,請參閱 錯誤和因應措施。

在上一個教學課程中,您已針對實體的基本 CRUD 作業 Student 實作一組網頁。 在本教學課程中,您會將排序、篩選和分頁功能新增至 [學生 索引] 頁面。 此外,還要建立將執行簡易群組的頁面。

下圖顯示當您完成時的頁面外觀。 資料行標題是使用者可以按一下以依據該資料行排序的連結。 重覆按一下資料行標題,可切換遞增和遞減排序次序。

Students_Index_page_with_paging

若要將排序新增至 [學生索引] 頁面,您將變更 Index 控制器的 方法 Student ,並將程式碼新增至 Student [索引] 檢視。

將排序功能新增至索引方法

Controllers\StudentController.cs中,以 Index 下列程式碼取代 方法:

public ActionResult Index(string sortOrder)
{
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";
   var students = from s in db.Students
                  select s;
   switch (sortOrder)
   {
      case "Name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "Date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:
         students = students.OrderBy(s => s.LastName);
         break;
   }
   return View(students.ToList());
}

此程式碼會從 URL 中的查詢字串接收 sortOrder 參數。 查詢字串值是由 ASP.NET MVC 作為動作方法的參數所提供。 該參數是 "Name" 或 "Date" 的字串,後面可選擇性地接著底線和字串 "desc" 來指定遞減順序。 預設排序順序為遞增。

第一次要求 [索引] 頁面時,沒有任何查詢字串。 學生會依 遞增順序 LastName 顯示,這是語句中 switch 遞減案例所建立的預設值。 使用者按一下資料行標題超連結時,適當的 sortOrder 值將會在查詢字串值中提供。

使用兩 ViewBag 個變數,讓檢視可以使用適當的查詢字串值來設定資料行標題超連結:

ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";

這些是三元陳述式。 第一個指定如果 sortOrder 參數為 null 或空白, ViewBag.NameSortParm 應該設定為 「name_desc」,否則應該設定為空字串。 這兩個陳述式讓檢視能夠設定資料行標題超連結,如下所示:

目前排序次序 姓氏超連結 日期超連結
姓氏遞增 descending ascending
姓氏遞減 ascending ascending
日期遞增 ascending descending
日期遞減 ascending ascending

方法會使用LINQ to Entities指定要排序依據的資料行。 程式碼會在 語句之前 switch 建立IQueryable變數、在 語句中 switch 修改它,並在 語句之後 switch 呼叫 ToList 方法。 當您建立和修改 IQueryable 變數時,沒有查詢會傳送至資料庫。 除非您藉由呼叫 之類的 ToList 方法,將 物件轉換成 IQueryable 集合,否則不會執行查詢。 因此,此程式碼會產生在 語句之前 return View 不會執行的單一查詢。

Views\Student\Index.cshtml中,以 <tr> 醒目提示的程式碼取代標題列的 和 <th> 元素:

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
        </th>
        <th>First Name
        </th>
        <th>
            @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {

此程式碼會使用屬性中 ViewBag 的資訊來設定具有適當查詢字串值的超連結。

執行頁面,然後按一下 [ 姓氏 ] 和 [ 註冊日期 ] 資料行標題,以確認排序是否正常運作。

顯示 Contoso University Students Index 頁面的螢幕擷取畫面。資料行標題為姓氏、名字和註冊日期。

按一下 [ 姓氏] 標題之後,學生會以遞減姓氏順序顯示。

顯示 Contoso University Students Index 頁面的螢幕擷取畫面,其中包含以遞減姓氏順序顯示的學生清單。

將搜尋方塊新增至學生索引頁面

若要將篩選新增至 Students 的 [索引] 頁面,您要將文字方塊和提交按鈕新增至檢視,並在 Index 方法中進行對應的變更。 文字方塊可讓您輸入要在名字和姓氏欄位中搜尋的字串。

將篩選功能新增至索引方法

Controllers\StudentController.cs中,將 方法取代 Index 為下列程式碼, (變更會反白顯示) :

public ViewResult Index(string sortOrder, string searchString)
{
    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
    var students = from s in db.Students
                   select s;
    if (!String.IsNullOrEmpty(searchString))
    {
        students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                               || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
    }
    switch (sortOrder)
    {
        case "name_desc":
            students = students.OrderByDescending(s => s.LastName);
            break;
        case "Date":
            students = students.OrderBy(s => s.EnrollmentDate);
            break;
        case "date_desc":
            students = students.OrderByDescending(s => s.EnrollmentDate);
            break;
        default:
            students = students.OrderBy(s => s.LastName);
            break;
    }

    return View(students.ToList());
}

您已將 searchString 參數新增至 Index 方法。 您也已將 子句新增至 LINQ 語句, where 這個子句只會選取名字或姓氏包含搜尋字串的學生。 搜尋字串值是從您要新增至 [索引] 檢視的文字方塊接收。只有在有要搜尋的值時,才會執行 where 子句的 語句。

注意

在許多情況下,您可以在 Entity Framework 實體集或記憶體內部集合上呼叫相同的方法。 結果通常相同,但在某些情況下可能不同。 例如,方法的.NET Framework實 Contains 作會在您傳遞空字串時傳回所有資料列,但 SQL Server Compact 4.0 的 Entity Framework 提供者會傳回空字串的零個數據列。 因此,範例中的程式碼 (將 語句放在 Where 語句內 if ,) 確定您取得所有版本SQL Server的結果相同。 此外,方法的.NET Framework實 Contains 作預設會執行區分大小寫的比較,但 Entity Framework SQL Server提供者預設會執行不區分大小寫的比較。 因此,呼叫 ToUpper 方法讓測試明確不區分大小寫可確保當您稍後變更程式碼以使用存放庫時不會變更結果,這會傳回 IEnumerable 集合,而不是 IQueryable 物件。 (當您在 IEnumerable 集合上呼叫 Contains 方法時,將取得 .NET Framework 實作;當您在 IQueryable 物件上呼叫它時,則會取得資料庫提供者實作。)

將搜尋方塊新增至學生的 [索引] 檢視

Views\Student\Index.cshtml中,在開頭 table 標記之前立即新增醒目提示的程式碼,以建立標題、文字方塊和[搜尋] 按鈕。

<p>
    @Html.ActionLink("Create New", "Create")
</p>

@using (Html.BeginForm())
{
    <p>
        Find by name: @Html.TextBox("SearchString")  
        <input type="submit" value="Search" /></p>
}

<table>
    <tr>

執行頁面,輸入搜尋字串,然後按一下 [ 搜尋 ] 以確認篩選是否正常運作。

Students_Index_page_with_search_box

請注意,URL 不包含 「an」 搜尋字串,這表示如果您將此頁面設為書簽,當您使用書簽時,將不會取得篩選的清單。 您稍後會變更 [搜尋 ] 按鈕,以在教學課程稍後使用篩選準則的查詢字串。

將分頁新增至 Students 索引頁面

若要將分頁新增至 Students Index 頁面,您將從安裝 PagedList.Mvc NuGet 套件開始。 然後,您將在 方法中 Index 進行其他變更,並將分頁連結新增至 Index 檢視。 PagedList.Mvc 是 ASP.NET MVC 的許多良好分頁和排序套件之一,此處的使用僅供範例使用,而不是針對其他選項的建議。 下圖顯示分頁連結。

[學生索引] 頁面的螢幕擷取畫面,其中顯示分頁連結。

安裝 PagedList.MVC NuGet 套件

NuGet PagedList.Mvc 套件會自動將 PagedList 套件安裝為相依性。 PagedList套件會 PagedList 安裝 和 IEnumerable 集合的 IQueryable 集合類型和擴充方法。 擴充方法會在集合 IQueryable 中從 或 IEnumerable 建立單一 PagedList 頁面的資料,而 PagedList 集合提供數個屬性和方法,以利分頁。 PagedList.Mvc套件會安裝顯示分頁按鈕的分頁協助程式。

從 [ 工具] 功能表中,選取 [NuGet 套件管理員 ],然後 選取 [管理方案的 NuGet 套件]。

在 [ 管理 NuGet 套件 ] 對話方塊中,按一下左側的 [ 線上 ] 索引標籤,然後在搜尋方塊中輸入 「paged」。 當您看到 PagedList.Mvc 套件時,按一下 [安裝]。

顯示 [管理 N u GET 套件] 對話方塊的螢幕擷取畫面。[線上] 索引標籤和填入頁面文字的搜尋列會反白顯示。已選取 [分頁清單] 套件。

在 [ 選取專案] 方塊中,按一下 [確定]。

顯示 [選取專案] 對話方塊的螢幕擷取畫面。已選取 [O K] 按鈕。

將分頁功能新增至索引方法

Controllers\StudentController.cs中,新增 using 命名空間的 PagedList 語句:

using PagedList;

以下列程式碼取代 Index 方法:

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
   ViewBag.CurrentSort = sortOrder;
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

   if (searchString != null)
   {
      page = 1;
   }
   else
   {
      searchString = currentFilter;
   }

   ViewBag.CurrentFilter = searchString;

   var students = from s in db.Students
                  select s;
   if (!String.IsNullOrEmpty(searchString))
   {
      students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                             || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
   }
   switch (sortOrder)
   {
      case "name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:  // Name ascending 
         students = students.OrderBy(s => s.LastName);
         break;
   }

   int pageSize = 3;
   int pageNumber = (page ?? 1);
   return View(students.ToPagedList(pageNumber, pageSize));
}

此程式碼會將參數、目前的排序次序參數和目前的篩選參數新增 page 至方法簽章,如下所示:

public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)

第一次顯示頁面,或是使用者尚未按一下分頁或排序連結時,所有參數都會是 null。 如果按一下分頁連結,變數 page 將會包含要顯示的頁碼。

A ViewBag 屬性會提供目前排序次序的檢視,因為這必須包含在分頁連結中,才能在分頁時保持排序次序相同:

ViewBag.CurrentSort = sortOrder;

另一個 屬性 ViewBag.CurrentFilter 會提供檢視與目前的篩選字串。 此值必須包含在分頁連結中,才能維護分頁期間的篩選設定,而且它必須在頁面重新顯示時還原為文字方塊。 如果搜尋字串在分頁期間變更,頁面必須重設為 1,因為新的篩選可能會導致顯示不同的資料。 在文字方塊中輸入值並按下送出按鈕時,搜尋字串就會變更。 在此情況下,參數 searchString 不是 Null。

if (searchString != null)
        page = 1;
else
    searchString = currentFilter;

方法結束時, ToPagedList students IQueryable 物件的擴充方法會將學生查詢轉換成支援分頁之集合類型中的單一學生頁面。 然後,該單一頁面的學生會傳遞至檢視:

int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));

ToPagedList 方法會採用頁面數。 這兩個問號代表 null 聯合運算子。 Null 聯合運算子將針對可為 Null 的型別定義預設值;(page ?? 1) 運算式表示在它含有值時會傳回值 page,或在 page 為 null 時傳回 1。

Views\Student\Index.cshtml中,以下列程式碼取代現有的程式碼:

@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc; 
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />

@{
    ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
}
<table>
<tr>
    <th></th>
    <th>
        @Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
    </th>
    <th>
        First Name
    </th>
    <th>
        @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
    </th>
</tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
            @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstMidName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
    </tr>
}

</table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

@Html.PagedListPager( Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter }) )

頁面頂端的 @model 陳述式指定檢視現在會取得 PagedList 物件,而不是 List 物件。

usingPagedList.Mvc 語句可讓您存取分頁按鈕的 MVC 協助程式。

此程式碼會使用 BeginForm 的多載,允許它指定 FormMethod.Get

@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
}

預設 BeginForm 會使用 POST 提交表單資料,這表示參數會傳入 HTTP 訊息本文,而不是在 URL 中做為查詢字串。 當您指定 HTTP GET 時,表單資料會以 URL 中作為查詢字串傳遞,這可讓使用者為該 URL 加上書籤。 使用 HTTP GET 的 W3C 指導方針指定當動作不會產生更新時,您應該使用 GET。

文字方塊會以目前的搜尋字串初始化,因此當您按一下新頁面時,您可以看到目前的搜尋字串。

Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)

資料行標頭連結會使用查詢字串,將目前的搜尋字串傳遞至控制器,讓使用者可以在篩選結果內排序:

@Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })

目前頁面和頁面總數隨即顯示。

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

如果沒有要顯示的頁面,則會顯示「第 0 頁為 0」。 (在此情況下,頁碼大於頁面計數,因為 Model.PageNumber 是 1,且 Model.PageCount 為 0.)

協助程式會顯示 PagedListPager 分頁按鈕:

@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )

協助 PagedListPager 程式提供許多選項供您自訂,包括 URL 和樣式。 如需詳細資訊,請參閱 GitHub 網站上的 TroyGoode / PagedList

執行頁面。

[學生索引] 頁面的螢幕擷取畫面。

以不同排序次序按一下分頁連結,以確定分頁運作正常。 然後輸入搜尋字串並再次嘗試分頁,以確認分頁的排序和篩選能正確運作。

顯示 [學生索引] 頁面的螢幕擷取畫面。在 [依名稱尋找搜尋列] 中輸入的字組。

建立顯示學生統計資料的 [關於] 頁面

對於 Contoso 大學網站的 About 頁面,您將顯示每個註冊日期已有多少學生註冊。 這需要對群組進行分組和簡單計算。 若要完成此工作,您需要執行下列作業:

  • 針對您需要傳遞至檢視的資料,建立檢視模型類別。
  • About修改控制器中的 Home 方法。
  • 修改檢 About 視。

建立檢視模型

建立 ViewModels 資料夾。 在該資料夾中,新增類別檔案 EnrollmentDateGroup.cs ,並以下列程式碼取代現有的程式碼:

using System;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.ViewModels
{
    public class EnrollmentDateGroup
    {
        [DataType(DataType.Date)]
        public DateTime? EnrollmentDate { get; set; }

        public int StudentCount { get; set; }
    }
}

修改 Home 控制器

HomeController.cs中,在檔案頂端新增下列 using 語句:

using ContosoUniversity.DAL;
using ContosoUniversity.ViewModels;

在類別的左大括弧之後,立即為資料庫內容新增類別變數:

public class HomeController : Controller
{
    private SchoolContext db = new SchoolContext();

以下列程式碼取代 About 方法:

public ActionResult About()
{
    var data = from student in db.Students
               group student by student.EnrollmentDate into dateGroup
               select new EnrollmentDateGroup()
               {
                   EnrollmentDate = dateGroup.Key,
                   StudentCount = dateGroup.Count()
               };
    return View(data);
}

LINQ 陳述式會依註冊日期將學生實體組成群組、計算每個群組中的實體數目、將結果儲存在 EnrollmentDateGroup 檢視模型物件的集合中。

Dispose新增方法:

protected override void Dispose(bool disposing)
{
    db.Dispose();
    base.Dispose(disposing);
}

修改 About 檢視

以下列程式碼取代 Views\Home\About.cshtml 檔案中的程式碼:

@model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
           
@{
    ViewBag.Title = "Student Body Statistics";
}

<h2>Student Body Statistics</h2>

<table>
    <tr>
        <th>
            Enrollment Date
        </th>
        <th>
            Students
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
        <td>
            @item.StudentCount
        </td>
    </tr>
}
</table>

執行應用程式,然後按一下 [ 關於 ] 連結。 每個註冊日期的學生人數將會顯示在資料表中。

About_page

選擇性:將應用程式部署至 Windows Azure

到目前為止,您的應用程式已在開發電腦上的本機IIS Express中執行。 若要讓其他人透過網際網路使用,您必須將其部署至 Web 主機提供者。 在本教學課程的這個選擇性區段中,您將將其部署至 Windows Azure 網站。

使用 Code First 移轉 部署資料庫

若要部署資料庫,您將使用 Code First 移轉。 當您建立用來設定從 Visual Studio 部署的設定的發行設定檔時,您將選取標示為 [執行] Code First 移轉 (在應用程式啟動時執行的核取方塊) 。 此設定會導致部署程式在目的地伺服器上自動設定應用程式 Web.config 檔案,讓 Code First 使用 MigrateDatabaseToLatestVersion 初始化運算式類別。

Visual Studio 不會在部署程式期間對資料庫執行任何動作。 當部署的應用程式第一次存取資料庫時,Code First 會自動建立資料庫,或將資料庫架構更新為最新版本。 如果應用程式實作 Migrations Seed 方法,方法會在建立資料庫或更新架構之後執行。

您的 Migrations Seed 方法會插入測試資料。 如果您要部署至生產環境,則必須變更 Seed 方法,使其只插入您想要插入生產資料庫的資料。 例如,在您的目前資料模型中,您可能想要有實際課程,但開發資料庫中虛構的學生。 您可以撰寫方法 Seed 以在開發中載入,然後在部署至生產環境之前批註虛構的學生。 或者,您可以撰寫方法 Seed 只載入課程,並使用應用程式的 UI 手動在測試資料庫中輸入虛構學生。

取得 Windows Azure 帳戶

您將需要 Windows Azure 帳戶。 如果您還沒有免費試用帳戶,只需幾分鐘的時間就可以建立免費試用帳戶。 如需詳細資訊,請參閱 Windows Azure 免費試用

在 Windows Azure 中建立網站和 SQL 資料庫

您的 Windows Azure 網站會在共用裝載環境中執行,這表示它會在與其他 Windows Azure 用戶端共用的虛擬機器上執行 (VM) 。 共用主控環境是一種在雲端中開始營運的低成本方法。 因為應用程式是在專用 VM 上執行,所以如果日後您的 Web 流量增加,可依需求對應用程式進行延展。 如果您需要更複雜的架構,您可以移轉至 Windows Azure 雲端服務。 雲端服務是執行於您可視本身需求來設定的專用 VM 上。

Windows Azure SQL 資料庫是雲端式關係資料庫服務,以SQL Server技術為基礎。 使用SQL Server的工具和應用程式也適用于SQL Database。

  1. Windows Azure 管理入口網站中,按一下左側索引標籤中的 [網站] ,然後按一下 [ 新增]。

    管理入口網站中的 [新增] 按鈕

  2. 按一下 [自訂建立]。

    顯示 [新增] 對話方塊的螢幕擷取畫面。[網站] 和 [自訂建立] 選項會反白顯示。

    [ 新增網站 - 自訂建立 精靈] 隨即開啟。

  3. 在精靈的 [ 新增網站] 步驟中,于 [URL ] 方塊中輸入字串,以作為應用程式的唯一 URL。 完整的 URL 將包含您在此處輸入的字串,加上您在文字方塊旁看到的尾碼。 此圖顯示 「ConU」,但可能採用該 URL,因此您必須選擇不同的 URL。

    在管理入口網站中使用資料庫連結建立

  4. 在 [ 區域 ] 下拉式清單中,選擇靠近您的區域。 此設定會指定您的網站將在哪個資料中心執行。

  5. 在 [ 資料庫 ] 下拉式清單中,選擇 [建立免費的 20 MB SQL 資料庫]。

    顯示 [建立網站] 對話方塊的螢幕擷取畫面。在 [資料庫] 下拉式清單中,選取 [選擇免費的 20 M B S Q L 資料庫]。核取記號按鈕會反白顯示。

  6. [資料庫連接字串名稱]中,輸入 SchoolCoNtext

    顯示 [建立網站] 對話方塊的螢幕擷取畫面。學校內容會填入 [D B 連接字串名稱] 文字欄位。核取記號按鈕會反白顯示。

  7. 按一下指向方塊底部右邊的箭號。 精靈會前進到 [資料庫設定] 步驟。

  8. 在 [ 名稱] 方塊中,輸入 ContosoUniversityDB

  9. 在 [伺服器]方塊中,選取 [新增SQL Database伺服器]。 或者,如果您先前已建立伺服器,您可以從下拉式清單中選取該伺服器。

  10. 輸入系統管理員 LOGIN NAMEPASSWORD。 如果選取 [新增 SQL Database 伺服器],則不要在此處輸入現有的名稱和密碼,而是輸入新的名稱和密碼;您現在定義的名稱和密碼將供未來存取資料庫時使用。 如果您選取先前建立的伺服器,您將輸入該伺服器的認證。 在本教學課程中,您不會選取 [ 進階 ] 核取方塊。 [ 進階 ] 選項可讓您設定資料庫 定序

  11. 選擇您為網站選擇的相同 區域

  12. 按一下方塊右下角的核取記號,指出您已完成。

    顯示 [指定資料庫設定] 對話方塊的螢幕擷取畫面,其中已選取所有設定,以及文字欄位中包含的範例密碼。核取記號按鈕會反白顯示。

    下圖顯示使用現有的 SQL Server 和 Login。

    新增網站的資料庫設定步驟 - 使用資料庫建立精靈

    管理入口網站會返回 [網站] 頁面,而 [ 狀態 ] 資料行會顯示正在建立網站。 一段時間後 (通常少於一分鐘) , [狀態 ] 資料行會顯示已成功建立網站。 在左側導覽列中,您在帳戶中擁有的網站數目會出現在 [網站 ] 圖示旁邊,而資料庫數目會出現在 [SQL Database ] 圖示旁邊。

將應用程式部署至 Windows Azure

  1. 在 Visual Studio 的 [方案總管] 中以滑鼠右鍵按一下專案,再選取內容功能表中的 [發佈]

    專案內容功能表中的 [發行]

  2. [發佈 Web精靈] 的 [設定檔] 索引標籤中,按一下 [匯入]。

    匯入發行設定

  3. 如果您先前尚未在 Visual Studio 中新增 Windows Azure 訂用帳戶,請執行下列步驟。 在這些步驟中,您會新增訂用帳戶,讓 [從 Windows Azure 網站 匯入] 底下的下拉式清單將包含您的網站。

    a. 在 [ 匯入發行設定檔 ] 對話方塊中,按一下 [從 Windows Azure 網站匯入],然後按一下 [ 新增 Windows Azure 訂用帳戶]。

    新增 Windows Azure 訂用帳戶

    b. 在 [ 匯入 Windows Azure 訂 用帳戶] 對話方塊中,按一下 [ 下載訂用帳戶檔案]。

    下載訂用帳戶檔案

    c. 在瀏覽器視窗中,儲存 .publishsettings 檔案。

    下載 .publishsettings 檔案

    警告

    安全性 - publishsettings 檔案包含您的認證 (未編碼的) ,用來管理 Windows Azure 訂用帳戶和服務。 此檔案的安全性最佳作法是暫時將它儲存在來原始目錄之外 (,例如在 Library\Documents 資料夾中) ,然後在匯入完成後將其刪除。 取得檔案存取權的 .publishsettings 惡意使用者可以編輯、建立和刪除您的 Windows Azure 服務。

    d. 在 [ 匯入 Windows Azure 訂 用帳戶] 對話方塊中,按一下 [ 流覽 ] 並流覽至 .publishsettings 檔案。

    下載子

    e. 按一下 [匯入] 。

    匯入

  4. 在 [ 匯入發行設定檔 ] 對話方塊中,選取 [從 Windows Azure 網站匯入],從下拉式清單中選取您的網站,然後按一下 [ 確定]。

    匯入發行設定檔

  5. 在 [ 連線] 索引 標籤中,按一下 [ 驗證連線 ],確定設定正確無誤。

    驗證連線

  6. 驗證連線後,[ 驗證連線 ] 按鈕旁邊會顯示綠色核取記號。 按一下 [下一步] 。

    已成功驗證連線

  7. 開啟SchoolCoNtext底下的[遠端連線字串]下拉式清單,然後選取您所建立資料庫的連接字串。

  8. 選取 [在應用程式啟動時執行Code First 移轉 (執行)

  9. 取消核取 [ 在執行時間針對UserCoNtext (DefaultConnection) 使用此連接字串,因為此應用程式未使用成員資格資料庫。

    [設定] 索引標籤

  10. 按一下 [下一步] 。

  11. [預覽] 索引標籤中,按一下 [ 開始預覽]。

    [預覽] 索引標籤中的 [開始預覽] 按鈕

    索引標籤會顯示將複製到伺服器的檔案清單。 顯示預覽並非發佈應用程式的必要專案,而是要注意的實用函式。 在此情況下,您不需要對顯示的檔案清單執行任何動作。 下次部署此應用程式時,只有已變更的檔案會在此清單中。

    StartPreview 檔案輸出

  12. 按一下 [發佈]。
    Visual Studio 會開始將檔案複製到 Windows Azure 伺服器的程式。

  13. [輸出] 視窗會顯示已採取的部署動作,並報告部署作業已順利完成。

    輸出視窗報告部署成功

  14. 部署成功時,預設瀏覽器會自動開啟至已部署網站的 URL。
    您建立的應用程式現在正在雲端中執行。 按一下 [學生] 索引標籤。

    Students_index_page_with_paging

此時,您的SchoolCoNtext資料庫已在 Windows Azure SQL 資料庫中建立,因為您選取了 [執行Code First 移轉 (在 app start) 上執行]。 已部署網站中的 Web.config 檔案已變更,因此 MigrateDatabaseToLatestVersion 初始化運算式會在程式碼第一次讀取或寫入資料庫中的資料時執行, (當您選取 [ Students ] 索引標籤時所發生) :

醒目提示 [將資料庫移轉至最新版本] 的程式碼螢幕擷取畫面。

部署程式也會建立新的連接字串 (SchoolCoNtext_DatabasePublish) ,讓Code First 移轉用來更新資料庫架構和植入資料庫。

Database_Publish連接字串

DefaultConnection連接字串適用于我們在本教學課程中未使用的成員資格資料庫 () 。 SchoolCoNtext連接字串適用于 ContosoUniversity 資料庫。

您可以在ContosoUniversity\obj\Release\Package\PackageTmp\Web.config中找到自己電腦上已部署Web.config檔案 的版本。 您可以使用 FTP 存取已部署 Web.config 檔案本身。 如需指示,請參閱 使用 Visual Studio ASP.NET Web 部署:部署程式碼更新。 遵循開頭為「若要使用 FTP 工具的指示,您需要三件事:FTP URL、使用者名稱和密碼」。

注意

Web 應用程式不會實作安全性,因此找到 URL 的任何人都可以變更資料。 如需如何保護網站的指示,請參閱使用成員資格、OAuth 和SQL Database部署安全 ASP.NET MVC 應用程式至 Windows Azure 網站。 您可以使用 Visual Studio 中的 Windows Azure 管理入口網站或 伺服器總 管來阻止其他人使用網站。

[伺服器總管] 的螢幕擷取畫面,其中顯示 [Windows Azure 網站] 索引標籤已展開,並在其下方選取 [Con U]。醒目提示 [停止網站] 選項的對話方塊功能表。

程式碼第一個初始化運算式

在部署區段中,您會看到正在使用 MigrateDatabaseToLatestVersion 初始化運算式。 Code First 也提供您可以使用的其他初始化運算式,包括 CreateDatabaseIfNotExists (預設) 、 DropCreateDatabaseIfModelChangesDropCreateDatabaseAlwaysDropCreateAlways初始化運算式可用於設定單元測試的條件。 您也可以撰寫自己的初始化運算式,如果您不想等到應用程式讀取或寫入資料庫,也可以明確地呼叫初始化運算式。 如需初始化運算式的完整說明,請參閱 程式設計實體架構 的第 6 章:由 Julie Lerman 和 Rowan Miller 撰寫的程式碼。

總結

在本教學課程中,您已瞭解如何建立資料模型,並實作基本的 CRUD、排序、篩選、分頁和群組功能。 在下一個教學課程中,您將展開資料模型,開始查看更進階的主題。

您可以在 ASP.NET 資料存取內容對應中找到其他 Entity Framework 資源的連結。