演练:使用存储过程检索实体类型(实体数据模型工具)

本主题演示如何使用存储过程检索实体类型的集合。 在本演练中,将使用 ADO.NET 实体数据模型设计器(实体设计器)导入存储过程,并创建返回实体类型集合的函数导入。

在概念模型中包含存储过程后,即可通过应用程序代码调用该存储过程。 将存储过程添加到概念模型的操作称为函数导入。 函数导入可返回简单类型、复杂类型、实体类型或不存在值的集合。

Cc716672.note(zh-cn,VS.100).gif注意:
若要函数导入返回 EntityType,则相应的存储过程返回的列必须与返回的 EntityType 的标量属性完全匹配。

当实体数据模型向导根据数据库生成 .edmx 文件时,它将在存储模型中针对数据库中的每一个存储过程创建对应的项。 创建函数导入后,对应项将添加到概念模型中。 有关创建函数导入的更多信息,请参见如何:导入存储过程(实体数据模型工具)

必备条件

若要完成本演练,必须生成 CourseManager 应用程序。 有关更多信息和说明,请参见实体框架快速入门。 生成该应用程序后,将通过创建基于 GetStudentGrades 存储过程的函数导入来修改其概念模型。

Cc716672.note(zh-cn,VS.100).gif注意:
因为本文档中的许多演练主题都使用该 CourseManager 应用程序作为起点,所以建议在本演练中使用 CourseManager 应用程序的副本,而不要编辑原始 CourseManager 代码。

本演练假定读者具备 Visual Studio、.NET Framework 的基本知识,并能使用 Visual C# 或 Visual Basic 进行编程。

创建函数导入

在本过程中,将创建基于 GetStudentGrades 存储过程(它包含在 CourseManager 应用程序的存储模型中)的函数导入。

创建函数导入

  1. 在 Visual Studio 中打开 CourseManager 解决方案。

  2. 在解决方案资源管理器中,双击 School.edmx 文件。

    此时将在 ADO.NET 实体数据模型设计器(实体设计器)中打开 School.edmx 文件,并且会打开**“模型浏览器”**窗口。

  3. 在**“模型浏览器”窗口中展开“EntityContainer: SchoolEntities”**节点。

    “实体集”、**“关联集”“函数导入”**文件夹在树视图中可见。

  4. 右击**“函数导入”并选择“添加函数导入”**。

    此时将打开“Add Function Import”对话框。

  5. 从**“存储过程名称”**下拉列表中选择“GetStudentGrades”。

  6. 在**“函数导入名称”**文本框中键入“GetStudentGrades”。

  7. 选择**“实体”**作为返回值,然后从相应的下拉列表中选择“StudentGrade”。

    Cc716672.note(zh-cn,VS.100).gif注意:
    因为 GetStudentGrades 存储过程(EnrollementIDStudentIDCourseIDGrade)返回的列与 StudentGrade 实体类型的标量属性完全匹配,所以可以将返回类型设置为 StudentGrade

  8. 单击**“确定”**。

    GetStudentGrades Function Import 将添加到概念模型。

构造用户界面

在本过程中,将向 CourseManager 应用程序的用户界面添加新窗体,以便查看所选学生的成绩。

构造用户界面

  1. 在**“解决方案资源管理器”中右击 CourseManager 项目,指向“添加”,然后选择“新建项”**。

    出现**“添加新项”**对话框。

  2. 选择**“Windows 窗体”,将窗体名称设置为“GradeViewer.vb”或“GradeViewer.cs”,然后单击“添加”**。

    新窗体即被添加到项目中,并在窗体设计器中打开。 窗体的名称设置为 GradeViewer,文本设置为 GradeViewer

  3. 从工具箱将 ComboBox 控件拖动到窗体,并在**“属性”窗口中将其“名称”**设置为 studentList

  4. 从工具箱将 DataGridView 控件拖动到窗体,并在**“属性”窗口中将其“名称”**设置为 gradeGridView

  5. 在**“解决方案资源管理器”**中双击 CourseViewer.vbCourseViewer.cs 文件。

    文件即在窗体设计器中打开。

  6. Button 控件拖动到窗体。 将其**“名称”设置为 viewGrades,并将其“文本”**设置为 View Grades

  7. 双击 viewGrades Button 控件。

    viewGrades_Click 事件处理程序即添加到代码隐藏文件。

  8. 将下面的代码添加到 viewGrades_Click 事件处理程序中:

    Dim gradeViewer As New GradeViewer()
    gradeViewer.Visible = True
    
    GradeViewer gradeViewer = new GradeViewer();
    gradeViewer.Visible = true;
    

现在,就完成了用户界面。

使用存储过程检索实体类型

在本过程中,将添加一些代码,用以执行先前根据 GetStudentGrades 存储过程创建的函数导入。 然后,代码将返回的 EntityType 集合绑定到 DataGridView 控件。 有关将对象绑定到控件的更多信息,请参见Binding Objects to Controls (Entity Framework)

使用存储过程检索实体类型

  1. 在窗体设计器中打开 GradeViewer 窗体后,双击窗体主体。

    此时将打开 GradeViewer 窗体的代码隐藏文件。

  2. 添加下面的 using (C#) 或 Imports (Visual Basic) 语句:

    Imports System.Data.Objects
    Imports System.Data.Objects.DataClasses
    
    using System.Data.Objects;
    using System.Data.Objects.DataClasses;
    
  3. 向表示对象上下文的 GradeViewer 类添加一个属性:

    ' Create an ObjectContext instance based on SchoolEntity.
    Private schoolContext As SchoolEntities
    
    // Create an ObjectContext instance based on SchoolEntity.
    private SchoolEntities schoolContext;
    
  4. GradeViewer_Load 事件处理程序中,添加下面的代码。 此代码初始化对象上下文,并将 ComboBox 控件的数据源设置为用于返回所有不具有 null EnrollmentDatePerson 类型的查询。

    ' Initialize schoolContext.
    schoolContext = New SchoolEntities()
    
    ' Define the query to retrieve students.
    Dim studentQuery As ObjectQuery(Of Person) = schoolContext _
        .People.Where("it.EnrollmentDate is not null") _
        .OrderBy("it.LastName")
    
    ' Execute and bind the studentList control to the query.
    studentList.DataSource = studentQuery _
        .Execute(MergeOption.OverwriteChanges)
    studentList.DisplayMember = "LastName"
    
    schoolContext = new SchoolEntities();
    
    // Define the query to retrieve students.
    ObjectQuery<Person> studentQuery = schoolContext.People
        .Where("it.EnrollmentDate is not null")
        .OrderBy("it.LastName");
    
    // Execute and bind the studentList control to the query.
    studentList.DataSource = studentQuery
        .Execute(MergeOption.OverwriteChanges);
    studentList.DisplayMember = "LastName";
    
  5. 返回 GradeViewer 窗体的设计视图,然后双击 studentList ComboBox 控件。

    studentList_SelectedIndexChanged 事件处理程序即添加到代码隐藏文件。

  6. 将下面的代码添加到 studentList_SelectedIndexChanged 事件处理程序中。 从下拉列表中选择新学生时,此代码执行 GetStudentGrades Function Import 并将结果绑定到 DataGridView 控件。

    ' Get the selected student so we can use the
    ' PersonID in the function import call.
    Dim currentStudent As Person = CType(Me.studentList _
        .SelectedItem(), Person)
    
    ' Set the data source for the gradeGridView
    ' to the results returned by the GetStudentGrades
    ' Function Import.
    gradeGridView.DataSource = schoolContext _
        .GetStudentGrades(currentStudent.PersonID)
    gradeGridView.Columns("Course").Visible = False
    gradeGridView.Columns("StudentID").Visible = False
    gradeGridView.Columns("Person").Visible = False
    gradeGridView.Columns("EnrollmentID").Visible = False
    gradeGridView.AllowUserToAddRows = False
    gradeGridView.AllowUserToDeleteRows = False
    
    // Get the selected student so we can use the
    // PersonID in the function import call.
    Person currentStudent = (Person)this.studentList
        .SelectedItem;
    
    // Set the data source for the gradeGridView
    // to the results returned by the GetStudentGrades
    // Function Import.
    gradeGridView.DataSource = schoolContext
        .GetStudentGrades(currentStudent.PersonID);
    gradeGridView.Columns["Course"].Visible = false;
    gradeGridView.Columns["StudentID"].Visible = false;
    gradeGridView.Columns["Person"].Visible = false;
    gradeGridView.Columns["EnrollmentID"].Visible = false;
    gradeGridView.AllowUserToAddRows = false;
    gradeGridView.AllowUserToDeleteRows = false;
    

按 Ctrl+F5 运行应用程序。 现在,在单击 View Grades 后从 Grade Viewer 窗体中的下拉列表中选择学生,即可查看学生成绩信息。

代码清单

本节包含 GradeViewer 窗体的代码隐藏文件的最终版本。

Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Public Class GradeViewer
    ' Create an ObjectContext instance based on SchoolEntity.
    Private schoolContext As SchoolEntities

    Private Sub GradeViewer_Load(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles MyBase.Load
        ' Initialize schoolContext.
        schoolContext = New SchoolEntities()

        ' Define the query to retrieve students.
        Dim studentQuery As ObjectQuery(Of Person) = schoolContext _
            .People.Where("it.EnrollmentDate is not null") _
            .OrderBy("it.LastName")

        ' Execute and bind the studentList control to the query.
        studentList.DataSource = studentQuery _
            .Execute(MergeOption.OverwriteChanges)
        studentList.DisplayMember = "LastName"
    End Sub

    Private Sub studentList_SelectedIndexChanged(ByVal sender As  _
        System.Object, ByVal e As System.EventArgs) Handles _
        studentList.SelectedIndexChanged
        ' Get the selected student so we can use the
        ' PersonID in the function import call.
        Dim currentStudent As Person = CType(Me.studentList _
            .SelectedItem(), Person)

        ' Set the data source for the gradeGridView
        ' to the results returned by the GetStudentGrades
        ' Function Import.
        gradeGridView.DataSource = schoolContext _
            .GetStudentGrades(currentStudent.PersonID)
        gradeGridView.Columns("Course").Visible = False
        gradeGridView.Columns("StudentID").Visible = False
        gradeGridView.Columns("Person").Visible = False
        gradeGridView.Columns("EnrollmentID").Visible = False
        gradeGridView.AllowUserToAddRows = False
        gradeGridView.AllowUserToDeleteRows = False
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace CourseManager
{
    public partial class GradeViewer : Form
    {
        // Create an ObjectContext instance based on SchoolEntity.
        private SchoolEntities schoolContext;

        public GradeViewer()
        {
            InitializeComponent();
        }

        private void GradeViewer_Load(object sender, EventArgs e)
        {
            schoolContext = new SchoolEntities();

            // Define the query to retrieve students.
            ObjectQuery<Person> studentQuery = schoolContext.People
                .Where("it.EnrollmentDate is not null")
                .OrderBy("it.LastName");

            // Execute and bind the studentList control to the query.
            studentList.DataSource = studentQuery
                .Execute(MergeOption.OverwriteChanges);
            studentList.DisplayMember = "LastName";
        }

        private void studentList_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Get the selected student so we can use the
            // PersonID in the function import call.
            Person currentStudent = (Person)this.studentList
                .SelectedItem;

            // Set the data source for the gradeGridView
            // to the results returned by the GetStudentGrades
            // Function Import.
            gradeGridView.DataSource = schoolContext
                .GetStudentGrades(currentStudent.PersonID);
            gradeGridView.Columns["Course"].Visible = false;
            gradeGridView.Columns["StudentID"].Visible = false;
            gradeGridView.Columns["Person"].Visible = false;
            gradeGridView.Columns["EnrollmentID"].Visible = false;
            gradeGridView.AllowUserToAddRows = false;
            gradeGridView.AllowUserToDeleteRows = false;
        }
    }
}

后续步骤

您已成功创建了可检索实体类型集合的函数导入。 有关如何生成使用实体框架的应用程序的更多信息,请参见ADO.NET Entity Framework

另请参见

其他资源

实体数据模型工具方案
实体数据模型工具任务