设计器查询存储过程

本分步演练演示了如何使用 Entity Framework Designer (EF Designer) 将存储过程导入模型,然后调用导入存储过程以检索结果。

请注意,Code First 不支持映射到存储过程或函数。 但可使用 System.Data.Entity.DbSet.SqlQuery 方法调用存储过程或函数。 例如:

var query = context.Products.SqlQuery("EXECUTE [dbo].[GetAllProducts]")`;

先决条件

若要完成此演练,您需要:

设置项目

  • 打开 Visual Studio 2012。
  • 选择“文件”->“新建”->“项目”
  • 在左窗格中,单击“Visual C#”,然后选择“控制台”模板
  • 输入“EFwithSProcsSample”作为名称
  • 选择“确定”

创建模型

  • 在“解决方案资源管理器”中右键单击该项目,然后选择“添加”->“新建项”

  • 从左侧菜单中选择“数据”,然后在“模板”窗格中选择“ADO.NET 实体数据模型”

  • 输入“EFwithSProcsModel.edmx”作为文件名,然后单击“添加”

  • 在“选择模型内容”对话框中,选择“从数据库生成”,然后单击“下一步”

  • 单击“新建连接”
    在“连接属性”对话框中,输入服务器名称(例如 (localdb)\mssqllocaldb),选择身份验证方法,键入 School 作为数据库名称,然后单击“确定”
    “选择数据连接”对话框将根据你的数据库连接设置进行更新。

  • 在“选择数据库对象”对话框中,选中“表”复选框以选择所有表
    此外,在“存储过程和函数”节点下选择以下存储过程:GetStudentGrades 和 GetDepartmentName

    导入存储过程

    从 Visual Studio 2012 开始,EF Designer 支持批量导入存储过程。 默认情况下,将选中“将所选存储过程和函数导入到实体模型”

  • 单击“完成”。

默认情况下,返回多个列的每个导入存储过程或函数的结果形状将自动成为新的复杂类型。 在本例中,我们希望将 GetStudentGrades 函数的结果映射到 StudentGrade 实体,并将 GetDepartmentName 的结果映射到“无”(“无”是默认值)

若要函数导入返回实体类型,则相应的存储过程返回的列必须与返回的实体类型的标量属性完全匹配。 函数导入也可返回简单类型、复杂类型或不存在值的集合。

  • 右键单击设计图面并选择“模型浏览器”
  • 在“模型浏览器”中,选择“函数导入”,然后双击“GetStudentGrades”函数
  • 在“编辑函数导入”对话框中,选择“实体”,然后选择“StudentGrade”
    通过“函数导入”对话框顶部的“函数导入是可组合的”复选框,可映射到可组合函数。 如果选中此框,则只有可组合函数(表值函数)会出现在“存储过程/函数名称”下拉列表中。 如果未选中此框,则列表中只会显示不可组合函数。

使用模型

打开 Program.cs 文件,其中定义了 Main 方法。 将以下代码添加到 Main 函数中。

该代码调用两个存储过程:GetStudentGrades(为指定的 StudentId 返回 StudentGrades)和 GetDepartmentName(在输出参数中返回部门的名称)。  

    using (SchoolEntities context = new SchoolEntities())
    {
        // Specify the Student ID.
        int studentId = 2;

        // Call GetStudentGrades and iterate through the returned collection.
        foreach (StudentGrade grade in context.GetStudentGrades(studentId))
        {
            Console.WriteLine("StudentID: {0}\tSubject={1}", studentId, grade.Subject);
            Console.WriteLine("Student grade: " + grade.Grade);
        }

        // Call GetDepartmentName.
        // Declare the name variable that will contain the value returned by the output parameter.
        ObjectParameter name = new ObjectParameter("Name", typeof(String));
        context.GetDepartmentName(1, name);
        Console.WriteLine("The department name is {0}", name.Value);

    }

编译并运行该应用程序。 该程序生成以下输出:

StudentID: 2
Student grade: 4.00
StudentID: 2
Student grade: 3.50
The department name is Engineering

输出参数

如果使用输出参数,则在完全读取结果之前,这些参数的值将不可用。 这是 DbDataReader 的基础行为所致;有关详细信息,请参阅使用 DataReader 检索数据