練習 - 將 ASP.NET 應用程式連線到 Azure SQL Database
您已經建立資料庫。 現在您可以設定及部署 Web 應用程式,供導師用來與學生討論課程和學習計劃。 該應用程式使用 System.Data.SqlClient
程式庫來擷取並顯示課程和課程模組的詳細資料,學生必須通過這些課程模組才算完成課程。
為了節省時間,我們使用既有的 Web 應用程式,並示範如何新增可將此應用程式連線至資料庫的程式碼。 下圖顯示此應用程式的主要元件:
若要設定 Web 應用程式,請執行下列作業:
- 建立「類別」,以保存課程名稱、課程模組標題,以及資料庫中每個課程模組的順序。
- 建立「資料存取控制器類別」,從資料庫擷取資訊。
- 編輯位於 Web 應用程式中索引頁背後的程式碼,以建立「資料存取控制器物件」並擷取資料。
- 編輯索引頁以顯示資料。
部署並執行既有的 Web 應用程式
將工作目錄切換至
education
資料夾。cd ~/education
執行下列命令以建立和部署初始 Web 應用程式。
WEBAPPNAME=educationapp-$RANDOM az webapp up \ --resource-group <rgn>[Sandbox resource group]</rgn> \ --location centralus \ --sku F1 \ --name $WEBAPPNAME
部署 Web 應用程式之後,輸出會顯示含有網站 URL 的 App_url。 在新索引標籤中開啟此網站。
您想要讓 Web 應用程式顯示課程清單,以及組成每個課程的課程模組。 目前,應用程式未擷取或顯示此資料。 因此,您必須更新程式碼,從資料庫取得並顯示資料。
在 Web 應用程式中新增程式碼以擷取資料
現在,讓我們在應用程式中新增程式碼,從資料庫擷取課程資料。
在 Cloud Shell 中,移至
education/Models
資料夾。cd ~/education/Models
此資料夾包含兩個檔案:
CoursesAndModules.cs
和DataAccessController.cs
。使用程式碼編輯器來開啟
CoursesAndModules.cs
檔案。code CoursesAndModules.cs
此檔案包含名為
CoursesAndModules
的空類別。namespace CoursesWebApp.Models { public class CoursesAndModules { // TODO: Define the CourseName, ModuleTitle, and Sequence read-only properties // TODO: Create a constructor that initializes the fields behind the properties } }
使用下列程式碼取代註解
// TODO: Define the CourseName, ModuleTitle, and Sequence read-only properties
。public string CourseName { get; } public string ModuleTitle { get; } public int Sequence { get; }
此程式碼定義一組唯讀欄位,其中包含 Web 應用程式顯示之每個資料列的資料。
將註解
// TODO: Create a constructor that initializes the fields behind the properties
換成下列建構函式。public CoursesAndModules(string courseName, string moduleTitle, int sequence) { this.CourseName = courseName; this.ModuleTitle = moduleTitle; this.Sequence = sequence; }
此建構函式在欄位中填入要顯示的資料。 完成的檔案應該包含下列程式碼。
namespace CoursesWebApp.Models { public class CoursesAndModules { public string CourseName { get; } public string ModuleTitle { get; } public int Sequence { get; } public CoursesAndModules(string courseName, string moduleTitle, int sequence) { this.CourseName = courseName; this.ModuleTitle = moduleTitle; this.Sequence = sequence; } } }
按 Ctrl+S 儲存檔案,然後按 Ctrl+Q 關閉程式碼編輯器。
使用程式碼編輯器來開啟
DataAccessController.cs
檔案。code DataAccessController.cs
此檔案包含名為
DataAccessController
的類別。 此類別包含資料存取邏輯,以連線到資料庫及擷取課程和課程模組資料。 還會將此資料填入一連串CoursesAndModules
物件中。using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; namespace CoursesWebApp.Models { public class DataAccessController { // TODO: Add your connection string in the following statements private string connectionString = "<Azure SQL Database Connection String>"; // Retrieve all details of courses and their modules public IEnumerable<CoursesAndModules> GetAllCoursesAndModules() { List<CoursesAndModules> courseList = new List<CoursesAndModules>(); // TODO: Connect to the database //using () { // TODO: Specify the Transact-SQL query to run // TODO: Execute the query // TODO: Read the data a row at a time // TODO: Close the database connection } return courseList; } } }
保持程式碼編輯器開啟,並切換至 Azure 入口網站。
在 Azure 入口網站功能表上,選取 [SQL 資料庫],然後選取資料庫。 coursedatabaseNNN 的 SQL 資料庫隨即出現。
在左側功能表窗格的 [設定] 下,選取 [連接字串]。 將 ADO.NET 連接字串複製到剪貼簿。
返回程式碼編輯器。 將 connectionString 變數的值取代為剪貼簿的值。 在連接字串中,看到值為
azuresql
的文字User ID
。 將文字{your_password}
換成此帳戶的密碼。private string connectionString = "Server=tcp:<server-name>.database.windows.net,1433;Initial Catalog=<database-name>;Persist Security Info=False;User ID=azuresql;Password=<password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
在註解
//TODO: Connect to the database
後面,將註解化的using
陳述式換成下列程式碼。using (SqlConnection con = new SqlConnection(connectionString))
此程式碼建立新的
SqlConnection
物件,以使用您的連接字串來連線至資料庫。將註解
// TODO: Specify the Transact-SQL query to run
取代為下列陳述式。SqlCommand cmd = new SqlCommand( @"SELECT c.CourseName, m.ModuleTitle, s.ModuleSequence FROM dbo.Courses c JOIN dbo.StudyPlans s ON c.CourseID = s.CourseID JOIN dbo.Modules m ON m.ModuleCode = s.ModuleCode ORDER BY c.CourseName, s.ModuleSequence", con); cmd.CommandType = CommandType.Text;
SqlCommand
物件包含 Transact-SQL (T-SQL) 陳述式來擷取所有課程和課程模組的資料。 還會使用dbo.StudyPlan
資料表中的資訊來聯結這些項目。使用下列程式碼取代註解
// TODO: Execute the query
。con.Open(); SqlDataReader rdr = cmd.ExecuteReader();
這些陳述式開啟資料庫的連線,並執行 T-SQL 陳述式。 您可以使用
SqlDataReader
物件來一次一列擷取結果。將註解
// TODO: Read the data a row at a time
換成下列程式碼區塊。while (rdr.Read()) { string courseName = rdr["CourseName"].ToString(); string moduleTitle = rdr["ModuleTitle"].ToString(); int moduleSequence = Convert.ToInt32(rdr["ModuleSequence"]); CoursesAndModules course = new CoursesAndModules(courseName, moduleTitle, moduleSequence); courseList.Add(course); }
此區塊逐一查看
SqlDataReader
物件中傳回的資料列。 程式碼擷取每個資料列中欄位的資料,並用來填入新的CoursesAndModules
物件。 然後此物件會新增至清單。將註解
// TODO: Close the database connection
取代為下列陳述式。con.Close();
此陳述式關閉資料庫的連線,並釋放任何已保留的資源。
完成的類別應該包含下列程式碼,其中包含資料庫的連接字串。
using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; namespace CoursesWebApp.Models { public class DataAccessController { // Add your connection string in the following statements private string connectionString = "Server=tcp:<server-name>.database.windows.net,1433;Initial Catalog=coursedatabase101;Persist Security Info=False;User ID=azuresql;Password=<password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"; // Retrieve all details of courses and their modules public IEnumerable<CoursesAndModules> GetAllCoursesAndModules() { List<CoursesAndModules> courseList = new List<CoursesAndModules>(); // Connect to the database using (SqlConnection con = new SqlConnection(connectionString)) { // Specify the Transact-SQL query to run SqlCommand cmd = new SqlCommand( @"SELECT c.CourseName, m.ModuleTitle, s.ModuleSequence FROM dbo.Courses c JOIN dbo.StudyPlans s ON c.CourseID = s.CourseID JOIN dbo.Modules m ON m.ModuleCode = s.ModuleCode ORDER BY c.CourseName, s.ModuleSequence", con); cmd.CommandType = CommandType.Text; // Execute the query con.Open(); SqlDataReader rdr = cmd.ExecuteReader(); // Read the data a row at a time while (rdr.Read()) { string courseName = rdr["CourseName"].ToString(); string moduleTitle = rdr["ModuleTitle"].ToString(); int moduleSequence = Convert.ToInt32(rdr["ModuleSequence"]); CoursesAndModules course = new CoursesAndModules(courseName, moduleTitle, moduleSequence); courseList.Add(course); } // Close the database connection con.Close(); } return courseList; } } }
儲存檔案並關閉 Code 編輯器。
將程式碼新增至 Web 應用程式以顯示資料
應用程式現在可以擷取課程資料。 現在,更新應用程式向使用者顯示資料。
在 Cloud Shell 中,移至
education/Pages
資料夾。cd ~/education/Pages
此資料夾包含 Web 應用程式用來顯示資訊的 .cshtml 頁面和程式碼檔案。
使用程式碼編輯器來開啟
Index.cshtml.cs
檔案。code Index.cshtml.cs
此檔案包含索引頁出現時執行的程式碼。 程式碼定義
CoursesAndModulesModel
類別。 索引頁使用此模型來顯示課程和課程模組的詳細資料。 在此檔案中,您需要新增程式碼以使用DataAccessController
物件來擷取該資料。using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CoursesWebApp.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace CoursesWebApp.Pages { public class CoursesAndModulesModel : PageModel { // TODO: Create a DataAccessController object // TODO: Create a collection for holding CoursesAndModules object public void OnGet() { // TODO: Retrieve the data using the DataAccessController object and populate the CoursesAndModules object } } }
在
Index.cshtml.cs
中,將註解// TODO: Create a DataAccessController object
換成下列程式碼,以建立新的DataAccessController
物件。DataAccessController dac = new DataAccessController();
使用下列程式碼取代註解
// TODO: Create a collection for holding CoursesAndModules object
。public List<CoursesAndModules> CoursesAndModules;
在
OnGet
方法中,將註解// TODO: Retrieve the data using the DataAccessController object and populate the CoursesAndModules object
換成下列程式碼。 此程式碼使用DataAccessController
物件,將來自資料庫的資料填入清單。CoursesAndModules = dac.GetAllCoursesAndModules().ToList();
完成的 檔案應該包含下列程式碼。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CoursesWebApp.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace CoursesWebApp.Pages { public class CoursesAndModulesModel : PageModel { // Create a DataAccessController object DataAccessController dac = new DataAccessController(); // Create a collection for holding CoursesAndModules object public List<CoursesAndModules> CoursesAndModules; public void OnGet() { // Retrieve the data using the DataAccessController object and populate the CoursesAndModules object CoursesAndModules = dac.GetAllCoursesAndModules().ToList(); } } }
儲存檔案並關閉程式碼編輯器。
使用程式碼編輯器來開啟
Index.cshtml
檔案。code Index.cshtml
此檔案包含索引頁的顯示邏輯。 還指定
CoursesAndModulesModel
作為資料來源。 我們新增的程式碼會建立並填入此模型。該頁面使用 HTML 資料來顯示來自模型的資料。 目前,此頁面只顯示表格標題。 表格內文 (
<tbody>
) 是空的。<h2>Courses and Modules</h2> <div> <table class="table"> <thead> <tr> <th> Course Name </th> <th> Modules </th> <th> Sequence </th> </tr> </thead> <tbody> <!-- TODO: Display the data from the CoursesAndModules collection --> </tbody> </table> </div>
將註解
<!-- TODO: Display the data from the CoursesAndModules collection --\>
取代為下列標記。@foreach(var courseAndModule in Model.CoursesAndModules) { <tr> <td> @Html.DisplayFor(courseName => courseAndModule.CourseName) </td> <td> @Html.DisplayFor(moduleTitle => courseAndModule.ModuleTitle) </td> <td> @Html.DisplayFor(sequence => courseAndModule.Sequence) </td> </tr> }
此程式碼逐一查看模型中的資料列,並在每個欄位中輸出資料。
完成的
Index.cshtml
檔案應該包含下列程式碼。@page @model CoursesAndModulesModel @{ ViewData["Title"] = "Home page"; } <h2>Courses and Modules</h2> <div> <table class="table"> <thead> <tr> <th> Course Name </th> <th> Modules </th> <th> Sequence </th> </tr> </thead> <tbody> @foreach(var courseAndModule in Model.CoursesAndModules) { <tr> <td> @Html.DisplayFor(courseName => courseAndModule.CourseName) </td> <td> @Html.DisplayFor(moduleTitle => courseAndModule.ModuleTitle) </td> <td> @Html.DisplayFor(sequence => courseAndModule.Sequence) </td> </tr> } </tbody> </table> </div>
儲存檔案並關閉程式碼編輯器。
部署並測試更新的 Web 應用程式
由於應用程式已完整設定來擷取課程資料並向使用者顯示,接下來可以部署更新的版本。
在 Cloud Shell 中,返回
education
資料夾。cd ~/education
執行下列命令以建立並部署更新的 Web 應用程式。
az webapp up \ --resource-group <rgn>[Sandbox resource group]</rgn> \ --name $WEBAPPNAME
部署新的 Web 應用程式之後,選取應用程式的連結。 現在應該會顯示課程和課程模組的清單,以及資料庫中儲存的資料。