实体框架 - 投影查询

LINQ 到实体

理解 LINQ to Entities 最重要的概念之一是它是一种声明性语言。重点在于定义您需要什么信息,而不是如何获取信息。

  • 这意味着您可以花更多时间处理数据,而花更少的时间试图找出执行访问数据库等任务所需的底层代码。

  • 重要的是要理解声明性语言实际上并没有从开发人员那里删除任何控制权,但它可以帮助开发人员将注意力集中在重要的事情上。

LINQ 到实体基本关键字

了解用于创建 LINQ 查询的基本关键字非常重要。只有几个关键字需要记住,但您可以以各种方式组合它们以获得特定结果。以下列表包含这些基本关键字并对每个关键字进行了简单的描述。

上阅读有关连接的更多信息
Sr. No. 关键字和说明
1

升序

指定排序操作从范围的最小(或最低)元素到范围的最高元素进行。这通常是默认设置。例如,执行字母排序时,排序范围从 A 到 Z。

2

指定用于实现分组的字段或表达式。字段或表达式定义用于执行分组任务的键。

3

降序

指定排序操作从范围中的最大(或最高)元素到范围中最小的元素进行。例如,当执行字母排序时,排序范围从 Z 到 A。

4

等于

用于连接语句的左子句和右子句之间,以将主上下文数据源连接到次上下文数据源。 equals 关键字左侧的字段或表达式指定主数据源,而 equals 关键字右侧的字段或表达式指定次数据源。

5

From

指定用于获取所需信息的数据源,并定义范围变量。此变量与用于循环中迭代的变量具有相同的用途。

6

Group

使用您指定的键值将输出组织成组。使用多个 group 子句可以创建多级输出组织。group 子句的顺序决定了特定键值在分组顺序中出现的深度。将此关键字与 by 组合以创建特定上下文。

7

In

有多种使用方式。在这种情况下,关键字确定用于查询的上下文数据库源。使用连接时,in 关键字用于连接使用的每个上下文数据库源。

8

Into

指定可用作 LINQ 查询子句(如 join、group 和 select)的引用的标识符。

9

Join

从两个相关数据源(例如在主/详细信息设置中)创建单个数据源。连接可以指定内部连接、组连接或左外部连接,其中内部连接为默认连接。您可以在msdn.microsoft.com

10

Let

定义一个范围变量,可用于将子表达式结果存储在查询表达式中。通常,范围变量用于提供额外的枚举输出或提高查询效率(这样特定任务(例如查找字符串的小写值)就不需要执行多次)。

11

On

指定用于实现连接的字段或表达式。该字段或表达式定义两个上下文数据源共有的元素。

12

Orderby

为查询创建排序顺序。您可以添加升序或降序关键字来控制排序顺序。使用多个 orderby 子句可以创建多个级别的排序。orderby 子句的顺序决定了处理排序表达式的顺序,因此使用不同的顺序将导致不同的输出。

13

Where

定义 LINQ 应从数据源检索的内容。您可以使用一个或多个布尔表达式来定义要检索的内容的具体内容。布尔表达式使用 && (AND) 和 || (OR) 运算符相互分隔。

14

Select

通过指定要返回的信息来确定 LINQ 查询的输出。此语句定义 LINQ 在迭代过程中返回的元素的数据类型。

投影

投影查询通过仅从数据库中检索特定字段来提高应用程序的效率。

  • 获得数据后,您可能希望根据需要对其进行投影或过滤,以在输出之前塑造数据。

  • 任何 LINQ to Entities 表达式的主要任务都是获取数据并将其作为输出提供。

本章的"开发 LINQ to Entities 查询"部分演示了执行此基本任务的技术。

让我们看一下以下代码,其中将检索学生列表。

using (var context = new UniContextEntities()) {

   var studentList = from s in context.Students select s;

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }
}

单个对象

要检索单个学生对象,您可以使用 First() 或 FirstOrDefault 可枚举方法,它们返回序列的第一个元素。First 和 FirstOrDefault 之间的区别在于,如果没有提供条件的结果数据,First() 将抛出异常,而如果没有结果数据,FirstOrDefault() 将返回默认值 null。在下面的代码片段中,将从列表中检索名字为 Ali 的第一个学生。

using (var context = new UniContextEntities()) {

   var student = (from s in context.Students where s.FirstMidName 
      == "Ali" select s).FirstOrDefault<Student>();

   string name = student.FirstMidName + " " + student.LastName;
   Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}

您还可以使用 Single() 或 SingleOrDefault 来获取单个学生对象,该对象返回序列的单个特定元素。在下面的示例中,检索到 ID 为 2 的单个学生。

using (var context = new UniContextEntities()) {

   var student = (from s in context.Students where s.ID 
      == 2 select s).SingleOrDefault<Student>();
   string name = student.FirstMidName + " " + student.LastName;
	
   Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   Console.ReadKey();
}

对象列表

如果您想要检索名字为 Ali 的学生列表,则可以使用 ToList() 可枚举方法。

using (var context = new UniContextEntities()) {

   var studentList = (from s in context.Students where s.FirstMidName 
      == "Ali" select s).ToList();

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

顺序

要按任何特定顺序检索数据/列表,您可以使用 orderby 关键字。在下面的代码中,学生的片段列表将按升序检索。

using (var context = new UniContextEntities()) {

   var studentList = (from s in context.Students orderby
      s.FirstMidName ascending select s).ToList();

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

标准与投影实体框架查询

假设您有一个包含 ID、FirstMidName、LastName 和 EnrollmentDate 的学生模型。如果您想返回学生列表,标准查询将返回所有字段。但如果您只想获取包含 ID、FirstMidName 和 LastName 字段的学生列表。这时您应该使用投影查询。以下是投影查询的简单示例。

using (var context = new UniContextEntities()) {

   var studentList = from s in context.Students
      orderby s.FirstMidName ascending
      where s.FirstMidName == "Ali"

   select new {s.ID, s.FirstMidName, s.LastName};

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

上述投影查询排除了 EnrollmentDate 字段。这将使您的申请速度更快。