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

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

若在实体数据模型 (EDM) 中包含存储过程,您就可以从应用程序代码中调用该存储过程。将存储过程添加到概念模型,这一操作称为 Function ImportFunction Import 可以返回简单类型或实体类型的集合,也可以不返回任何值。

Note注意

若要 Function Import 返回 EntityType,则相应的存储过程返回的列必须与返回的 EntityType 的属性完全匹配。

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

系统必备

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

Note注意

因为本文档中的许多演练主题都使用该 CourseManager 应用程序作为起点,所以建议在本演练中使用 CourseManager 应用程序的副本,而不要编辑原始 CourseManager 代码。

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

创建函数导入

在本过程中,将创建基于 GetStudentGrades 存储过程(它包含在 CourseManager EDM 的存储模型中)的 Function Import

创建函数导入

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

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

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

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

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

  4. 右键单击**“函数导入”并选择“创建函数导入”**。

    此时,将打开 New Function Import 对话框。

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

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

  7. 从**“返回类型”**下拉列表中选择 CourseGrade

    Note注意

    因为 GetStudentGrades 存储过程(EnrollementIDGrade)返回的列与 CourseGrade 实体类型的标量属性完全匹配,所以可以将返回类型设置为 CourseGrade

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

    GetStudentGradesFunction Import 即被添加到 EDM。

构造用户界面

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

构造用户界面

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

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

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

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

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

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

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

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

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

  7. 双击 viewGradesButton 控件。

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

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

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

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

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

在本过程中,将添加一些代码,用以执行先前根据 GetStudentGrades 存储过程创建的 Function Import。然后,代码将返回的 EntityType 集合绑定到 DataGridView 控件。有关将对象绑定到控件的更多信息,请参见将对象绑定到控件(实体框架)

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

  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 控件的数据源设置为用于返回所有不具有 nullEnrollmentDatePerson 类型的查询。

    ' Initialize schoolContext.
    schoolContext = New SchoolEntities()
    
    ' Define the query to retrieve students.
    Dim studentQuery As ObjectQuery(Of Person) = schoolContext _
        .Person.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.Person
        .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 窗体的设计视图,然后双击 studentListComboBox 控件。

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

  6. 将下面的代码添加到 studentList_SelectedIndexChanged 事件处理程序中。从下拉列表中选择新学生时,此代码执行 GetStudentGradesFunctionImport 并将结果绑定到 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)
    
    // 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);
    

按 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 _
            .Person.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)
    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.Person
                .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);
        }
    }
}

后续步骤

您已成功创建了可检索实体类型集合的 Function Import。有关实体框架中的存储过程支持的更多信息,请参见存储过程支持(实体框架)。有关如何生成使用实体框架的应用程序的更多信息,请参见编程指南(实体框架)

另请参见

其他资源

ADO.NET 实体数据模型设计器方案
实体数据模型工具任务