实体框架 – 投影查询
实体框架 – 投影查询
LINQ 到实体
理解 LINQ to Entities 的最重要概念之一是它是一种声明性语言。重点是定义您需要什么信息,而不是如何获取信息。
-
这意味着您可以花更多的时间处理数据,而花更少的时间试图找出执行任务(例如访问数据库)所需的底层代码。
-
重要的是要了解声明式语言实际上并没有从开发人员那里删除任何控制,但它可以帮助开发人员将注意力集中在重要的事情上。
LINQ to Entities 基本关键字
了解用于创建 LINQ 查询的基本关键字很重要。只需要记住几个关键字,但您可以通过各种方式组合它们以获得特定结果。以下列表包含这些基本关键字,并提供了对每个关键字的简单描述。
Sr. No. | 关键字和描述 |
---|---|
1 |
Ascending 指定从范围的最小(或最低)元素到范围的最高元素进行排序操作。这通常是默认设置。例如,在执行字母排序时,排序将在从 A 到 Z 的范围内。 |
2 |
By 指定用于实现分组的字段或表达式。字段或表达式定义用于执行分组任务的键。 |
3 |
Descending 指定从范围的最大(或最高)元素到范围的最低元素进行排序操作。例如,在执行字母排序时,排序范围是从 Z 到 A。 |
4 |
Equals 用于连接语句的 left 和 right 子句之间,以将主上下文数据源连接到辅助上下文数据源。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 的 Student 模型。如果要返回学生列表,标准查询将返回所有字段。但是,如果您只想获取包含 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 字段。这将使您的应用程序更快。