LINQ to Entities详解

2024-02-29 02:32
文章标签 详解 linq entities

本文主要是介绍LINQ to Entities详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相关概念

在开始了解LINQ to Entities之前,需要先对.NET Framework 3.5版本后对C#语言的几个扩展特性做一些阐释,这有助于我们更容易、更深刻的理解LINQ to Entities技术的原理与实现。

一、隐式实例化局部变量

.NET Framework 3.5后,实例化局部变量语法有了新的选择:使用“var”关键字隐式类型化:

var user = new User();

隐式类型化语法与Javascript语言里声明变量的语法类似,它可以一定程度上简化实例化局部变量的语法。但如果隐式实例化的作用仅限于此,那本文不会专门提及。隐式类型化更重要的用途是用于匿名类型的实例化。

需要提醒注意的是,只有局部变量实例化允许使用隐式实例化语法。这表示私有变量实例化无法享受该福利;同时,仅声明变量或实例化对象为null也是不允许使用隐式实例化语法的。

二、对象初始化

对象初始化指在实例化对象时,即可对对象的属性进行赋值:

1 var user = new User()
2 {
3     ID = Guid.NewGuid(),
4     Account = "Apollo"
5 };
三、匿名类型

LINQ to Entities的Select可以将实体类型投影为匿名类型,所以有必要对匿名类型作简单介绍。匿名类型指的是不显示声明类型的细节,而是根据上下文环境需要,临时声明满足需要的类型。由于该类型是临时需要的,所以不必为之命名。匿名类型的声明语法如下:

var user = new { ID = Guid.NewGuid(), Name = "Apollo" };
四、扩展方法

扩展方法是微软为扩展已有框架而创造的一个语法糖,.NET Framework 3.5就是通过很多扩展方法实现了对.NET Framework 2.0的升级扩展的。扩展方法很神奇,被扩展的对象可以不知道扩展方法的存在,就能在行为上得到扩展。扩展方法也很蹩脚,如果使用者不知情,很可能不知道对象具有扩展行为;抑或知道有扩展方法,但是不知道要引用哪个扩展库以使其支持扩展的行为。扩展方法的语法如下:

复制代码
1 public static class UserExt
2 {
3     public static void Drink(this User user, object water)
4     {
5 6     }
7 }
复制代码
五、Lambda表达式

Lambda表达式是由委托以及匿名方法发展而来的,它可将表达式或代码块(匿名方法)赋给一个变量,从而以最少量的输入实现编码目的。Lambda表达式一般配合IEnumerable<T>的静态扩展方法使用,完成对象集合的快捷查询操作。Lambda表达式的语法如下:

var user = db.Users.FirstOrDefault(o => o.Account == "Apollo");
六、标准查询操作符

System.Linq.Enumerable静态类声明了一套标准查询操作符(Standard Query Operators,SQO)方法集合。标准查询操作符的语法和标准SQL很相似,这不是偶然,而是微软有意为之,以使熟悉SQL的程序员们更容易上手。标准查询操作符的基本语法如下:

复制代码
1 using (var db = new EntityContext())
2 {
3     var roles = from o in db.Users
4                where o.Account == "Apollo"
5                select o.Roles;
6 7 }
复制代码

标准查询操作符和Lambda表达式的关系非常密切。编译器会将上诉表达式转化为下列以Lambda表达式为参数的显式扩展方法调用序列:

1 using (var db = new EntityContext())
2 {
3     var roles = db.Users.Where(o => o.Account == "Apollo").Select(o => o.Roles);
4 }

 

标准查询操作符

接下来,将针对数据查询操作中常用的条件查询、投影、分区、排序、分组、集合、元素、量词和聚集等标准查询操作符进行分类介绍。

一、条件操作符

条件操作符Where类似于SQL中的WHERE子句,用于实现条件查询。下列扩展方法表达式查询满足条件“角色不为空”的用户集合:

var user = db.Users.Where(o => o.Roles != null);

对应的标准查询操作符表达式为:

1 var users = from o in db.Users
2             where o.Roles != null
3             select o;
二、投影操作符

投影操作符Select类似于SQL中的SELECT子句,将对象投影为一个匿名类型实例,用于控制指定查询迭代器显示或者处理的对象属性。另外,需要注意的是,扩展方法表达式中的Select操作符并非必须的,省略模式下,会返回完整的被投影对象。下列扩展方法表达式将用户的帐号和密码信息投影为一个匿名类型:

var users = db.Users.Select(o => new { o.Account, o.Password });

对应的标准查询操作符表达式为:

1 var users = from o in db.Users
2             select new { o.Account, o.Password };
三、分区操作符

分区操作符实现对象的分区操作。其中,Take操作符类似于SQL中的TOP操作符,下列扩展方法表达式返回前5个用户对象:

var users = db.Users.OrderBy(o => o.Roles.Count).Take(5);

Skip操作符用于跳过指定个数对象并返回序列中的剩余对象,下列扩展方法表达式返回除前10个用户外的剩余用户:

var users = db.Users.OrderBy(o => o.Roles.Count).Skip(10);

TakeWhile操作符用于返回条件表达式值为真时的相邻元素集合,下列扩展方法表达式返回第一个拥有3个角色的用户之前的所有用户集合:

var users = db.Users.OrderBy(o => o.Roles.Count).TakeWhile(o => o.Roles.Count == 3);

SkipWhile操作符用于跳过条件表达式值为真时的元素,并返回剩下的元素集合,下列扩展方法表达式返回第一个拥有3个角色的用户之后的所有用户集合:

var users = db.Users.OrderBy(o => o.Roles.Count).SkipWhile(o => o.Roles == 3);
四、排序操作符

排序操作符实现对象的排序功能,包括OrderBy、OrderByDescending、ThenBy、ThenByDescending和Reverse五个操作符。其中OrderBy操作符实现对象的升序排列,相当于SQL中的ORDER BY ASC子句,下列扩展方法表达式实现用户按拥有的角色数进行升序排列:

var users = db.Users.OrderBy(o => o.Roles.Count);

对应的标准查询操作符表达式为:

1 var users = from o in db.Users
2             orderby o.Roles.Count
3             select o;

OrderByDescending操作符实现对象的降序排列,相当于SQL中的ORDER BY DESC子句,下列扩展方法表达式实现用户按拥有的角色数进行降序排列:

var users = db.Users.OrderByDescending(o => o.Roles.Count);

对应的标准查询操作符表达式为:

1 var users = from o in db.Users
2             orderby o.Roles.Count descending
3             select o;

ThenBy、ThenByDescending和Reverse操作符只能针对IOrderedEnumerable接口对象使用,所以一般紧跟在OrderBy/OrderByDesending操作符方法后使用。ThenBy操作符由编译器翻译为对OrderBy操作符的再次调用;ThenByDescending操作符由编译器翻译为对OrderByDescending操作符的再次调用;Reverse操作符实现对象的排序反向。这里不再一一举例。

五、分组操作符

分组操作符GroupBy类似于SQL中的GROUP BY子句,实现对象的分组操作。下列扩展方法表达式实现用户对象按拥有的角色数量进行分组:

var users = db.Users.GroupBy(o => o.Roles.Count);

对应的标准查询操作符表达式为:

1 var users = from o in db.Users
2             group o by o.Roles.Count into g
3             select new { RoleCount = g.Key, Group = g };
六、集合操作符

集合操作符包括Distinct、Union、intersect和Except四个操作符,除Distinct外,其他三个操作符都可将两个序列组合成一个序列。Distinct操作符类似于SQL中的DISTINCT关键字,用于删除序列中具有重复值的对象。下列扩展方法表达式实现将用户角色中的重复角色删除功能:

var roles = user.Roles.Distinct();

Union操作符类似于SQL中的UNION关键字,用于求具有同样结构的两个序列的并集。下列扩展方法表达式实现将用户1和用户2所拥有的角色组合成一个角色集合,并排除其中重复的角色:

var roles = user1.Roles.Union(user2.Roles);

Intersect操作符类似于SQL中的INTERSECT关键字,用于求具有同样结构的两个序列的交集。下列扩展方法表达式返回用户1和用户2都具有的角色集合:

var roles = user1.Roles.Intersect(user2.Roles);

Except操作符类似于SQL中的EXCEPT关键字,用于返回第一个序列中有、但第二个序列中没有的对象集合。下列扩展方法表达式返回用户1拥有,而用户2没有的角色集合:

var roles = user1.Roles.Except(user2.Roles);
七、元素操作符

元素操作符包括两组操作符,分别是用于从一个IEnumerable<T>序列中返回满足条件的单个对象或无满足条件对象时抛异常的First、Last和Single操作符,以及返回满足条件的单个对象或无满足条件对象时返回空对象的FirstOrDefault、LastOrDefault和SingleOrDefault操作符。其中First和FirstOrDefault操作符用于返回第一个满足条件的对象。下列扩展方法表达式返回第一个拥有三个角色的用户:

var user = db.Users.FirstOrDefault(o => o.Roles.Count == 3);

Last和LastOrDefault操作符用于返回最后一个满足条件的对象。下列扩展方法表达式返回最后一个拥有三个角色的用户:

var user = db.Users.LastOrDefault(o => o.Roles.Count == 3);

Single和SingleOrDefault操作符用于返回满足条件的序列中的唯一元素,如果序列中包含不止一个元素,将会抛异常。下列扩展方法表达式返回帐号为“Apollo”的唯一用户,如果有多个用户帐号都为“Apollo”,则抛异常:

var user = db.Users.SingleOrDefault(o => o.Account == "Apollo");
八、量词操作符

量词操作符包括 Any、All和Contains三个操作符,用于检查序列中是否有一些对象或所有对象满足条件。其中,Any操作符用于检查序列中是否有任何一个对象满足条件。下列扩展方法表达式当有任何一个用户拥有三个角色时返回真,否则返回假:

var result = db.Users.Any(o => o.Roles.Count == 3);

All操作符用于检查序列中是否所有对象均满足条件。下列扩展方法表达式当所有用户均拥有三个角色时返回真,否则返回假:

var result = db.Users.All(o => o.Roles.Count == 3);

Contains操作符用于检查序列中是否包含指定的对象。下列扩展方法表达式当集合中包含用户1则返回真,否则返回假:

var result = db.Users.Where(o => o.Roles.Count == 3).Contains(user1);
九、聚集操作符

聚集操作符包括Count、Min、Max、Sum和Average等多个操作符,用于对对象集合进行统计计算。其中,Count操作符类似于SQL中的COUNT关键字,用于计算序列中满足条件的对象个数。下列扩展方法表达式返回拥有3个角色的用户数量:

var result = db.Users.Count(o => o.Roles.Count == 3);

Min操作符类似于SQL中的MIN关键字,用于返回按条件计算的最小值。下列扩展方法表达式返回拥有最少角色数量的用户所拥有的角色数量:

var result = db.Users.Min(o => o.Roles.Count);

Max操作符类似于SQL中的MAX关键字,用于返回按条件计算的最大值。下列扩展方法表达式返回拥有角色数量最多的用户所拥有的角色数量:

var result = db.Users.Max(o => o.Roles.Count);

Sum操作符类似于SQL中的SUM关键字,用于返回按条件计算的总数。下列扩展方法表达式返回已赋予用户的所有角色总数:

var result = db.Users.Sum(o => o.Roles.Count);

Average操作符类似于SQL中的AVERAGE关键字,用于返回按条件计算的平均值。下列扩展方法表达式,用于返回用户所拥有的角色平均数:

var result = db.Users.Average(o => o.Roles.Count);

 

总结

本文首先给出了LINQ技术的官方实现集合,以及LINQ to Entities实现的技术细节;然后概要介绍了与LINQ to Entities相关的几个基本概念;最后对LINQ to Entities常用的标准查询操作符的使用进行了分类介绍,从中也可以看出LINQ to Entities和SQL的功能基本是一一对应的。

这篇关于LINQ to Entities详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/757316

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式,包括目标范围内FIFO(Target-Scoped)、DMA FIFO以及点对点流(Peer-to-Peer)。 FIFO类型 **目标范围FIFO(Target-Sc

019、JOptionPane类的常用静态方法详解

目录 JOptionPane类的常用静态方法详解 1. showInputDialog()方法 1.1基本用法 1.2带有默认值的输入框 1.3带有选项的输入对话框 1.4自定义图标的输入对话框 2. showConfirmDialog()方法 2.1基本用法 2.2自定义按钮和图标 2.3带有自定义组件的确认对话框 3. showMessageDialog()方法 3.1

脏页的标记方式详解

脏页的标记方式 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了有效地管理这些脏页并确保数据的一致性,数据库需要对脏页进行标记。了解脏页的标记方式对于理解数据库的内部工作机制和优化性能至关重要。 二、脏页产生的过程 当数据库中的数据被修改时,这些修改首先会在内存中的缓冲池(Buffer Pool)中进行。例如,执行一条 UPDATE 语句修改了某一行数据,对应的缓

OmniGlue论文详解(特征匹配)

OmniGlue论文详解(特征匹配) 摘要1. 引言2. 相关工作2.1. 广义局部特征匹配2.2. 稀疏可学习匹配2.3. 半稠密可学习匹配2.4. 与其他图像表示匹配 3. OmniGlue3.1. 模型概述3.2. OmniGlue 细节3.2.1. 特征提取3.2.2. 利用DINOv2构建图形。3.2.3. 信息传播与新的指导3.2.4. 匹配层和损失函数3.2.5. 与Super

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配(Exact Match)2. 正则表达式匹配(Regex Match)3. 前缀匹配(Prefix Match) 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中,location 指令用于定义如何处理特定的请求 URI。由于网站往往需要不同的处理方式来适应各种请求,NGINX 提供了多种匹