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

相关文章

一文深入详解Python的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现