擷取和顯示資料與模型繫結和 web formRetrieving and displaying data with model binding and web forms

本系列教學課程示範使用 ASP.NET Web Form 專案中的模型繫結的基本層面。This tutorial series demonstrates basic aspects of using model binding with an ASP.NET Web Forms project. 模型繫結進行更簡單的比處理資料來源物件 (例如 ObjectDataSource 或 SqlDataSource) 的資料互動。Model binding makes data interaction more straight-forward than dealing with data source objects (such as ObjectDataSource or SqlDataSource). 此系列簡介資料的開頭,並在稍後的教學課程中將移至更進階的概念。This series starts with introductory material and moves to more advanced concepts in later tutorials.

模型繫結模式適用於任何資料存取技術。The model binding pattern works with any data access technology. 在本教學課程中,您將使用 Entity Framework,但您可以使用最熟悉的資料存取技術。In this tutorial, you will use Entity Framework, but you could use the data access technology that is most familiar to you. 從資料繫結的伺服器控制項,例如 GridView、 ListView、 DetailsView 或 FormView 控制項,您可以指定要用於選取、 更新、 刪除和建立資料方法的名稱。From a data-bound server control, such as a GridView, ListView, DetailsView, or FormView control, you specify the names of the methods to use for selecting, updating, deleting, and creating data. 在本教學課程中,您會指定 SelectMethod 值。In this tutorial, you will specify a value for the SelectMethod.

在該方法中,您提供的邏輯擷取資料。Within that method, you provide the logic for retrieving the data. 在下一個教學課程中,您將 UpdateMethod、 DeleteMethod 和 InsertMethod 設定值。In the next tutorial, you will set values for UpdateMethod, DeleteMethod and InsertMethod.

您可以下載完整的專案,在C#或 Visual Basic。You can download the complete project in C# or Visual Basic. 可下載的程式碼適用於使用 Visual Studio 2012 和更新版本。The downloadable code works with Visual Studio 2012 and later. 它會使用 Visual Studio 2012 範本,也就是本教學課程中的 Visual Studio 2017 範本稍有不同。It uses the Visual Studio 2012 template, which is slightly different than the Visual Studio 2017 template shown in this tutorial.

在本教學課程中,您可以執行應用程式在 Visual Studio 中。In the tutorial you run the application in Visual Studio. 您也可以部署到裝載提供者應用程式,並使其可透過網際網路使用。You can also deploy the application to a hosting provider and make it available over the internet. Microsoft 提供免費的 web 裝載中的最多 10 個 web sitesMicrosoft offers free web hosting for up to 10 web sites in a
免費 Azure 試用帳戶free Azure trial account. 如需有關如何將 Visual Studio web 專案部署至 Azure App Service Web Apps 的資訊,請參閱使用 Visual Studio 的 ASP.NET Web 部署系列。For information about how to deploy a Visual Studio web project to Azure App Service Web Apps, see the ASP.NET Web Deployment using Visual Studio series. 該教學課程也會示範如何使用 Entity Framework Code First Migrations,將 SQL Server 資料庫部署到 Azure SQL Database。That tutorial also shows how to use Entity Framework Code First Migrations to deploy your SQL Server database to Azure SQL Database.

在本教學課程中使用的軟體版本Software versions used in the tutorial

  • Microsoft Visual Studio 2017 或 Microsoft Visual Studio Community 2017Microsoft Visual Studio 2017 or Microsoft Visual Studio Community 2017

本教學課程也適用於 Visual Studio 2012 和 Visual Studio 2013,但有一些差異,在使用者介面和專案範本。This tutorial also works with Visual Studio 2012 and Visual Studio 2013, but there are some differences in the user interface and project template.

您將建置What you'll build

在本教學課程中,您將會:In this tutorial, you'll:

  • 建立與註冊課程的學生反映一所大學的資料物件Build data objects that reflect a university with students enrolled in courses
  • 建置從物件的資料庫資料表Build database tables from the objects
  • 填入測試資料的資料庫Populate the database with test data
  • 在 web 表單中顯示資料Display data in a web form

建立專案Create the project

  1. 在 Visual Studio 2017 中,建立ASP.NET Web 應用程式 (.NET Framework) 專案,稱為ContosoUniversityModelBindingIn Visual Studio 2017, create a ASP.NET Web Application (.NET Framework) project called ContosoUniversityModelBinding.

    建立專案

  2. 選取 [確定]。Select OK. 若要選取範本的對話方塊隨即出現。The dialog box to select a template appears.

    選取 web form

  3. 選取 Web Form範本。Select the Web Forms template.

  4. 如有必要,驗證變更為個別使用者帳戶If necessary, change the authentication to Individual User Accounts.

  5. 選取 [確定] 建立專案。Select OK to create the project.

修改網站的外觀Modify site appearance

變更幾個自訂網站的外觀。Make a few changes to customize site appearance.

  1. 開啟 Site.Master 檔。Open the Site.Master file.

  2. 變更要顯示的標題Contoso 大學而非My ASP.NET ApplicationChange the title to display Contoso University and not My ASP.NET Application.

    <title><%: Page.Title %> - Contoso University</title>
    
  3. 變更中的標頭文字應用程式名稱Contoso 大學Change the header text from Application name to Contoso University.

    <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" runat="server" href="~/">Contoso University</a>
    </div>
    
  4. 變更導覽標頭連結至適當的站台。Change the navigation header links to site appropriate ones.

    移除的連結關於連絡人,相反地,連結到學生頁面上,您將建立。Remove the links for About and Contact and, instead, link to a Students page, which you will create.

    <ul class="nav navbar-nav">
        <li><a runat="server" href="~/">Home</a></li>
        <li><a runat="server" href="~/Students">Students</a></li>
    </ul>
    
  5. 儲存 Site.Master。Save Site.Master.

新增 web 表單,以顯示學生資料Add a web form to display student data

  1. 在 [方案總管] 中,以滑鼠右鍵按一下您的專案,然後選取新增,然後新項目In Solution Explorer, right-click your project, select Add and then New Item.

  2. 加入新項目對話方塊中,選取使用主版頁面的 Web Form範本並將它命名Students.aspxIn the Add New Item dialog box, select the Web Form with Master Page template and name it Students.aspx.

    建立頁面

  3. 選取 [新增]。Select Add.

  4. Web form 主版頁面,選取Site.MasterFor the web form's master page, select Site.Master.

  5. 選取 [確定]。Select OK.

加入資料模型Add the data model

模型資料夾中,加入名為類別UniversityModels.csIn the Models folder, add a class named UniversityModels.cs.

  1. 以滑鼠右鍵按一下模型,選取新增,然後新項目Right-click Models, select Add, and then New Item. [新增項目] 對話方塊隨即出現。The Add New Item dialog box appears.

  2. 從左側的導覽功能表中,選取程式碼,然後類別From the left navigation menu, select Code, then Class.

    建立模型類別

  3. 將類別命名為UniversityModels.cs ,然後選取新增Name the class UniversityModels.cs and select Add.

    這個檔案中定義SchoolContextStudentEnrollment,和Course類別,如下所示:In this file, define the SchoolContext, Student, Enrollment, and Course classes as follows:

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.ComponentModel.DataAnnotations;
    
    namespace ContosoUniversityModelBinding.Models
    {
        public class SchoolContext : DbContext
        {
            public DbSet<Student> Students { get; set; }
            public DbSet<Enrollment> Enrollments { get; set; }
            public DbSet<Course> Courses { get; set; }
        }
    
        public class Student
        {
            [Key, Display(Name = "ID")]
            [ScaffoldColumn(false)]
            public int StudentID { get; set; }
    
            [Required, StringLength(40), Display(Name="Last Name")]
            public string LastName { get; set; }
    
            [Required, StringLength(20), Display(Name = "First Name")]
            public string FirstName { get; set; }
    
            [EnumDataType(typeof(AcademicYear)), Display(Name = "Academic Year")]
            public AcademicYear Year { get; set; }
    
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    
        public class Enrollment
        {
            [Key]
            public int EnrollmentID { get; set; }
            public int CourseID { get; set; }
            public int StudentID { get; set; }
            public decimal? Grade { get; set; }
            public virtual Course Course { get; set; }
            public virtual Student Student { get; set; }
        }
    
        public class Course
        {
            [Key]
            public int CourseID { get; set; }
            public string Title { get; set; }
            public int Credits { get; set; }
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        } 
    
        public enum AcademicYear
        {
            Freshman,
            Sophomore,
            Junior,
            Senior
        }
    }
    

    SchoolContext類別衍生自DbContext,其管理資料庫連接,並變更資料中。The SchoolContext class derives from DbContext, which manages the database connection and changes in the data.

    Student類別,您會發現要套用的屬性FirstNameLastName,和Year屬性。In the Student class, notice the attributes applied to the FirstName, LastName, and Year properties. 本教學課程會使用這些屬性進行資料驗證。This tutorial uses these attributes for data validation. 若要簡化程式碼,只有這些屬性會標示具有資料驗證屬性。To simplify the code, only these properties are marked with data-validation attributes. 在實際的專案中,您會將驗證屬性套用至需要驗證的所有屬性。In a real project, you would apply validation attributes to all properties needing validation.

  4. 儲存 UniversityModels.cs。Save UniversityModels.cs.

將類別為基礎的資料庫設定Set up the database based on classes

本教學課程會使用Code First 移轉建立物件和資料庫資料表。This tutorial uses Code First Migrations to create objects and database tables. 這些資料表會儲存資訊的學生和他們的課程。These tables store information about the students and their courses.

  1. 選取 工具 > NuGet 套件管理員 > Package Manager ConsoleSelect Tools > NuGet Package Manager > Package Manager Console.

  2. Package Manager Console,執行下列命令:In Package Manager Console, run this command:
    enable-migrations -ContextTypeName ContosoUniversityModelBinding.Models.SchoolContext

    如果命令成功完成時,會出現一則訊息指出已啟用移轉。If the command completes successfully, a message stating migrations have been enabled appears.

    啟用移轉

    請注意,名為的檔案Configuration.cs已建立。Notice that a file named Configuration.cs has been created. Configuration類別具有Seed方法,它可以預先填入測試資料的資料庫資料表。The Configuration class has a Seed method, which can pre-populate the database tables with test data.

在資料庫中預先填入Pre-populate the database

  1. 開啟 Configuration.cs。Open Configuration.cs.

  2. 將下列程式碼加入至 Seed 方法。Add the following code to the Seed method. 此外,新增using陳述式ContosoUniversityModelBinding. Models命名空間。Also, add a using statement for the ContosoUniversityModelBinding. Models namespace.

    namespace ContosoUniversityModelBinding.Migrations
    {
        using System;
        using System.Data.Entity;
        using System.Data.Entity.Migrations;
        using System.Linq;
        using ContosoUniversityModelBinding.Models;
    
        internal sealed class Configuration : DbMigrationsConfiguration<SchoolContext>
        {
            public Configuration()
            {
                AutomaticMigrationsEnabled = false;
            }
    
            protected override void Seed(SchoolContext context)
            {
    
                context.Students.AddOrUpdate(
                     new Student { 
                         FirstName = "Carson", 
                         LastName = "Alexander", 
                         Year = AcademicYear.Freshman },
                     new Student { 
                         FirstName = "Meredith", 
                         LastName = "Alonso", 
                         Year = AcademicYear.Freshman },
                     new Student { 
                         FirstName = "Arturo", 
                         LastName = "Anand", 
                         Year = AcademicYear.Sophomore },
                     new Student { 
                         FirstName = "Gytis", 
                         LastName = "Barzdukas", 
                         Year = AcademicYear.Sophomore },
                     new Student { 
                         FirstName = "Yan", 
                         LastName = "Li", 
                         Year = AcademicYear.Junior },
                     new Student { 
                         FirstName = "Peggy", 
                         LastName = "Justice", 
                         Year = AcademicYear.Junior },
                     new Student { 
                         FirstName = "Laura", 
                         LastName = "Norman", 
                         Year = AcademicYear.Senior },
                     new Student { 
                         FirstName = "Nino", 
                         LastName = "Olivetto", 
                         Year = AcademicYear.Senior }
                     );
    
                context.SaveChanges();
    
                context.Courses.AddOrUpdate(
                    new Course { Title = "Chemistry", Credits = 3 },
                    new Course { Title = "Microeconomics", Credits = 3 },
                    new Course { Title = "Macroeconomics", Credits = 3 },
                    new Course { Title = "Calculus", Credits = 4 },
                    new Course { Title = "Trigonometry", Credits = 4 },
                    new Course { Title = "Composition", Credits = 3 },
                    new Course { Title = "Literature", Credits = 4 }
                    );
    
                context.SaveChanges();
    
                context.Enrollments.AddOrUpdate(
                    new Enrollment { StudentID = 1, CourseID = 1, Grade = 1 },
                    new Enrollment { StudentID = 1, CourseID = 2, Grade = 3 },
                    new Enrollment { StudentID = 1, CourseID = 3, Grade = 1 },
                    new Enrollment { StudentID = 2, CourseID = 4, Grade = 2 },
                    new Enrollment { StudentID = 2, CourseID = 5, Grade = 4 },
                    new Enrollment { StudentID = 2, CourseID = 6, Grade = 4 },
                    new Enrollment { StudentID = 3, CourseID = 1 },
                    new Enrollment { StudentID = 4, CourseID = 1 },
                    new Enrollment { StudentID = 4, CourseID = 2, Grade = 4 },
                    new Enrollment { StudentID = 5, CourseID = 3, Grade = 3 },
                    new Enrollment { StudentID = 6, CourseID = 4 },
                    new Enrollment { StudentID = 7, CourseID = 5, Grade = 2 }
                    );
    
                context.SaveChanges();
            }
        }
    }
    
  3. 儲存 Configuration.cs。Save Configuration.cs.

  4. 在 [套件管理員] 主控台中,執行命令新增移轉初始In the Package Manager Console, run the command add-migration initial.

  5. 執行命令更新資料庫Run the command update-database.

    如果執行此命令中時,您會收到例外狀況StudentIDCourseID值可能不同於Seed方法值。If you receive an exception when running this command, the StudentID and CourseID values might be different from the Seed method values. 開啟這些資料庫資料表,並尋找現有的值,如StudentIDCourseIDOpen those database tables and find existing values for StudentID and CourseID. 將這些值加入的程式碼植入Enrollments資料表。Add those values to the code for seeding the Enrollments table.

新增 GridView 控制項Add a GridView control

填入的資料庫的資料,您現在準備好擷取該資料並加以顯示。With populated database data, you're now ready to retrieve that data and display it.

  1. 開啟 Students.aspx。Open Students.aspx.

  2. 找出MainContent預留位置。Locate the MainContent placeholder. 在該預留位置中,新增GridView包括此程式碼的控制項。Within that placeholder, add a GridView control that includes this code.

    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <asp:GridView runat="server" ID="studentsGrid"
            ItemType="ContosoUniversityModelBinding.Models.Student" DataKeyNames="StudentID" 
            SelectMethod="studentsGrid_GetData"
            AutoGenerateColumns="false">
            <Columns>
                <asp:DynamicField DataField="StudentID" />
                <asp:DynamicField DataField="LastName" />
                <asp:DynamicField DataField="FirstName" />
                <asp:DynamicField DataField="Year" />          
                <asp:TemplateField HeaderText="Total Credits">
                  <ItemTemplate>
                    <asp:Label Text="<%# Item.Enrollments.Sum(en => en.Course.Credits) %>" 
                        runat="server" />
                  </ItemTemplate>
                </asp:TemplateField>        
            </Columns>
        </asp:GridView>
    </asp:Content>
    

    要注意的事項:Things to note:

    • 請注意,設定的值SelectMethodGridView 項目中的屬性。Notice the value set for the SelectMethod property in the GridView element. 這個值會指定用來擷取您在下一個步驟中建立的 GridView 資料的方法。This value specifies the method used to retrieve GridView data, which you create in the next step.

    • ItemType屬性設定為Student稍早建立的類別。The ItemType property is set to the Student class created earlier. 此設定可讓您參考的標記中的類別屬性。This setting allows you to reference class properties in the markup. 例如,Student類別具有名為EnrollmentsFor example, the Student class has a collection named Enrollments. 您可以使用Item.Enrollments來擷取該集合,然後使用LINQ 語法擷取每個學生的註冊點數總和。You can use Item.Enrollments to retrieve that collection and then use LINQ syntax to retrieve each student's enrolled credits sum.

  3. 儲存 Students.aspx。Save Students.aspx.

加入程式碼來擷取資料Add code to retrieve data

在 Students.aspx 程式碼後置檔案中,新增為指定的方法SelectMethod值。In the Students.aspx code-behind file, add the method specified for the SelectMethod value.

  1. 開啟 Students.aspx.cs。Open Students.aspx.cs.

  2. 新增using陳述式ContosoUniversityModelBinding. ModelsSystem.Data.Entity命名空間。Add using statements for the ContosoUniversityModelBinding. Models and System.Data.Entity namespaces.

    using ContosoUniversityModelBinding.Models;
    using System.Data.Entity;
    
  3. 新增您指定的方法SelectMethod:Add the method you specified for SelectMethod:

    public IQueryable<Student> studentsGrid_GetData()
    {
        SchoolContext db = new SchoolContext();
        var query = db.Students.Include(s => s.Enrollments.Select(e => e.Course));
        return query;
    }
    

    Include子句可改善查詢效能,但並非必要。The Include clause improves query performance but isn't required. 不含Include子句,資料會使用擷取消極式載入,其中包含每次傳送至資料庫的個別查詢相關的擷取資料。Without the Include clause, the data is retrieved using lazy loading, which involves sending a separate query to the database each time related data is retrieved. 具有Include子句,資料會使用擷取積極式載入,這表示單一資料庫查詢會擷取所有相關的資料。With the Include clause, data is retrieved using eager loading, which means a single database query retrieves all related data. 如果不使用相關的資料,積極式載入是比較沒有效率因為擷取詳細資料。If related data isn't used, eager loading is less efficient because more data is retrieved. 不過,在此情況下,積極式載入可讓您獲得最佳效能因為相關的資料會顯示每一筆記錄。However, in this case, eager loading gives you the best performance because the related data is displayed for each record.

    如需載入時的效能考量的詳細資訊的相關資料,請參閱 < 「 延遲 」、 「 Eager 和 「 明確載入相關資料的一節中讀取相關資料,與 ASP.NET 中的 Entity FrameworkMVC 應用程式文章。For more information about performance considerations when loading related data, see the Lazy, Eager, and Explicit Loading of Related Data section in the Reading Related Data with the Entity Framework in an ASP.NET MVC Application article.

    根據預設,資料會依照標示為索引鍵屬性的值而定。By default, the data is sorted by the values of the property marked as the key. 您可以新增OrderBy子句來指定不同的排序值。You can add an OrderBy clause to specify a different sort value. 在此範例中,預設值StudentID屬性用來排序。In this example, the default StudentID property is used for sorting. 排序、 分頁和篩選資料文章中,使用者可選取的資料行排序。In the Sorting, Paging, and Filtering Data article, the user is enabled to select a column for sorting.

  4. 儲存 Students.aspx.cs。Save Students.aspx.cs.

執行您的應用程式Run your application

執行您的 web 應用程式 (F5) 並瀏覽至學生網頁,當中會顯示下列:Run your web application (F5) and navigate to the Students page, which displays the following:

顯示資料

自動產生的模型繫結方法Automatic generation of model binding methods

在逐步進行本教學課程系列,只要到您的專案複製程式碼從本教學課程。When working through this tutorial series, you can simply copy the code from the tutorial to your project. 不過,這種方法的缺點是功能的,您可能不會察覺到自動產生的模型繫結方法的程式碼的 Visual Studio 所提供。However, one disadvantage of this approach is that you may not become aware of the feature provided by Visual Studio to automatically generate code for model binding methods. 您自己的專案上工作時,自動產生程式碼可以節省時間,並且有助於您深入了解如何實作的作業。When working on your own projects, automatic code generation can save you time and help you gain a sense of how to implement an operation. 本章節描述的自動程式碼產生功能。This section describes the automatic code generation feature. 本章節僅供參考,並不包含任何您需要在您的專案中實作的程式碼。This section is only informational and does not contain any code you need to implement in your project.

設定的值時SelectMethodUpdateMethodInsertMethod,或DeleteMethod屬性的標記程式碼中,您可以選取建立的新方法選項。When setting a value for the SelectMethod, UpdateMethod, InsertMethod, or DeleteMethod properties in the markup code, you can select the Create New Method option.

建立方法

Visual Studio 不僅會建立具有適當簽章中,程式碼後置中的方法,也會產生執行作業的實作程式碼。Visual Studio not only creates a method in the code-behind with the proper signature, but also generates implementation code to perform the operation. 如果您先設定ItemType屬性,才能使用自動程式碼產生功能,為作業輸入產生的程式碼使用。If you first set the ItemType property before using the automatic code generation feature, the generated code uses that type for the operations. 例如,當設定UpdateMethod屬性,下列程式碼會自動產生:For example, when setting the UpdateMethod property, the following code is automatically generated:

// The id parameter name should match the DataKeyNames value set on the control
public void studentsGrid_UpdateItem(int id)
{
    ContosoUniversityModelBinding.Models.Student item = null;
    // Load the item here, e.g. item = MyDataLayer.Find(id);
    if (item == null)
    {
        // The item wasn't found
        ModelState.AddModelError("", String.Format("Item with id {0} was not found", id));
        return;
    }
    TryUpdateModel(item);
    if (ModelState.IsValid)
    {
        // Save changes here, e.g. MyDataLayer.SaveChanges();

    }
}

同樣地,此程式碼不需要加入至專案。Again, this code doesn't need to be added to your project. 在下一個教學課程中,您將實作更新、 刪除和加入新資料的方法。In the next tutorial, you'll implement methods for updating, deleting, and adding new data.

總結Summary

在本教學課程中,您可以建立資料模型類別,並從那些類別產生資料庫。In this tutorial, you created data model classes and generated a database from those classes. 您會將資料庫資料表中填入測試資料。You filled the database tables with test data. 您用來從資料庫擷取資料的模型繫結,然後 GridView 中顯示資料。You used model binding to retrieve data from the database, and then displayed the data in a GridView.

在接下來教學課程在本系列中,您將會讓更新、 刪除和建立資料。In the next tutorial in this series, you'll enable updating, deleting, and creating data.