C#进阶-LINQ表达式基础语法

简介: 本篇文章我们将演示LINQ扩展包的基础语法,以Select查询、Count计数、Average平均值、OrderBy排序函数为例,目前LINQ支持两种语法,我会在每个案例前先用大家熟知的SQL语句表达,再在后面用C#的两种LINQ语法分别实现。LINQ语法第一次接触难免感到陌生,最好的学习方式就是在项目中多去使用,相信会有很多感悟。

基础语法

在学习之前,我们要做一些准备工作,我们需要创建User对象和包含User对象的集合,作为后面查询和输出的数据源,参见这篇文章C#进阶之LINQ表达式总结完成准备工作。

数据源:


1、Select 查询

/* SQL里的表达: 查找用户里职业是医生的人的姓名,按照年龄倒序输出 */selectnamefromuserwhereoccupation="Doctor"orderbyagedesc;
/* C#版本1 */List<string>nameList= (fromuinlistwhereu.occupation=="Doctor"orderbyu.agedescendingselectu.name).ToList();
/* C#版本2 */List<string>nameList=list.OrderByDescending(u=>u.age).Where(p=>p.occupation=="Doctor").Select(x=>x.name).ToList();

LiuGuangzhi, LiuZiming, LiuShuai/* 输出结果 */

其中,C#版本1的语法是 from 变量名 in 集合 where 条件 orderby 条件 select 结果变量,得到的结果是LINQ的内置类型<Enumerable>,可直接视为匿名类型(var),需用.ToList()转换为List<string>类型。C#版本2是LINQ的一种扩展写法,是更加常用的写法。


2、Count 计数

/* SQL里的表达: 查找用户里姓Zhang的女性教师的数量*/selectcount(*) fromuserwhereoccupation="Teacher"andnamelike'Zhang%'andgender=false;
/* C#版本1 */intcount= (fromuinlistwhereu.occupation=="Teacher"where!u.genderwhereu.name.StartsWith("Zhang") selectu).Count();
/* C#版本2 */intcount=list.Count(u=>u.occupation=="Teacher"&&!u.gender&&u.name.StartsWith("Zhang"));

1/* 输出结果 */

3、Average 平均值

/* SQL里的表达: 查找用户里姓Liu的小于40岁的医生的平均年龄 */selectavg(age) fromuserwhereoccupation="Doctor"andnamelike'Liu%'andage<40;
/* C#版本1 */doubleaverageNum= (fromuinlistwhereu.occupation=="Doctor"whereu.age<40whereu.name.StartsWith("Liu") selectu.age).Average();
/* C#版本2 */doubleaverageNum=list.Where(u=>u.occupation=="Doctor"&&u.age<40&&u.name.StartsWith("Liu")).Select(u=>u.age).Average();

35/* 输出结果 */

4、Max/Min/Sum/ 最大/小值/总和

这里仅需参考LINQ求平均值的例子,求最大/小值或者总和时,只需要把C#语句末尾的.Average()方法替换成.Max()/.Min()/.Sum()即可。


5、OrderBy 排序

/* SQL里的表达: 查找用户里名字带Jin的人,优先按照年龄倒序,其次按照姓氏拼音正序,输出这些人的全部信息 */select*fromuserwherenamelike'%Jin%'orderbyagedescnameasc;
/* C#版本1 */List<User>userList= (fromuinlistwhereu.name.Contains("Jin") orderbyu.agedescendingorderbyu.nameselectu).ToList();
/* C#版本2 */List<User>userList=list.Where(u=>u.name.Contains("Jin")).OrderByDescending(u=>u.age).OrderBy(u=>u.name).ToList();

{id=10, name=HuJin, age=21, gender=False, occupation=Student}, 
{id=7, name=LiuJin, age=21, gender=True, occupation=Builder}, 
{id=2, name=ZhangJin, age=18, gender=False, occupation=Student} /* 输出

6、 Any/All 函数

Any()函数判断判断是否至少存在一个符合元素符合条件;All()函数判断是否全部元素都符合条件;下面以Any()函数为例:

/* SQL里的表达: 查找用户里是否存在年龄小于30岁职业是医生的女性 */selectcount(*) fromuserwhereoccupation="Doctor"andgender=falseandage<30; //返回符合的个数
/* C#版本1 */boolresult= (fromuinlistwhereu.age<30where!u.genderwhereu.occupation=="Doctor"selectu).Any();
/* C#版本2 */boolresult=list.Any(u=>u.age<30&&!u.gender&&u.occupation=="Doctor");

数据源中所有医生如下:

可以看到,目前我们数据源里是有Liu Shuai这一条符合三个属性(小于30岁/医生/女性)的。

true/* 输出结果 */

这里Any()函数是只要存在至少一个符合全部条件的结果,即返回布尔值True,只有在一个都不符合条件的情况下才会返回False;与之相反,All()函数只有在全部数据都符合全部条件的情况下,才会返回True,只要有一条不满足就返回False;All()函数的语法和Any()函数的语法相同,上面的例子把Any()直接替换成All()即可。


7、Single/SingleOrDefault 函数

Single()判断是否只有一个元素符合条件,若成立则返回该元素,若不成立则抛出异常。

/* SQL里的表达: 查找用户里年龄小于30岁职业是医生的女性 */select*fromuserwhereoccupation="Doctor"andgender=falseandage<30
/* C#版本1 */UseruserResult= (fromuinlistwhereu.age<30where!u.genderwhereu.occupation=="Doctor"selectu).Single();
/* C#版本2 */UseruserResult=list.Single(u=>u.age<30&&!u.gender&&u.occupation=="Doctor");

{id=6, name=LiuShuai, age=29, gender=False, occupation=Doctor} /* 输出结果 */

Single()要求有且只有一条满足要求的数据,多条满足条件或一条也没有,此方法会报错;

SingleOrDefault()要求最多有一条满足要求的数据,多条满足条件,此方法会报错;没有数据则返回数据类型的默认值;

类似的还有First()、FirstOrDefault()、Last()、LastOrDefault(),这里给大家做了一个异常表格记录了各种情况的返回值:

函数 没有满足 一条满足 多条满足 list本身为Null
Single 异常 该元素 异常 异常
SingleOrDefault 默认值 该元素 异常 异常
First 异常 该元素 第一个元素 异常
FirstOrDefault 默认值 该元素 第一个元素 异常
Last 异常 该元素 末尾的元素 异常
LastOrDefault 默认值 该元素 末尾的元素 异常

面对可能出现的异常,我们一般在使用这类方法时要进行Try{…}Catch(…){…}。


8、Skip/Take/Top 函数

/* SQL里的表达: 查找用户表自然排序第4个人到第6个人的姓名*/selectnamefromuserlimit3,3;
/* C#版本1 */List<string>nameList= (fromuinlistselectu.name).Skip(3).Take(3).ToList();
/* C#版本2 */List<string>nameList=list.Skip(3).Take(3).Select(x=>x.name).ToList();

LiuGuangzhi, LiuZiming, LiuShuai/* 输出结果 */

同理,Top(n)表示截取前n条数据。

目录
相关文章
|
4月前
|
开发框架 自然语言处理 .NET
C#一分钟浅谈:LINQ 查询表达式的使用技巧
【9月更文挑战第6天】LINQ(Language Integrated Query)是C#开发中的强大工具,使查询数据集合变得简单且接近自然语言。本文从基础入手,通过具体示例讲解LINQ查询表达式的使用技巧,包括过滤、排序和分组等操作。同时,文章还探讨了常见问题及解决方法,如性能优化、过早枚举和类型转换等,帮助开发者写出更高效、易维护的代码。
107 15
|
8月前
|
C#
C#的基本语法结构学习
【5月更文挑战第17天】C#基础语法包括变量(如`int x = 10`)、常量(`const int MAX_VALUE = 100`)、运算符(如算术和比较运算符)、控制语句(if、for、while等)和函数声明(`int Add(int x, int y) { return x + y; }`)。这些构成C#程序的基本元素。
89 0
|
4月前
|
C#
C#一分钟浅谈:Lambda 表达式和匿名方法
本文详细介绍了C#编程中的Lambda表达式与匿名方法,两者均可用于定义无名函数,使代码更简洁易维护。文章通过基础概念讲解和示例对比,展示了各自语法特点,如Lambda表达式的`(parameters) =&gt; expression`形式及匿名方法的`delegate(parameters)`结构。并通过实例演示了两者的应用差异,强调了在使用Lambda时应注意闭包问题及其解决策略,推荐优先使用Lambda表达式以增强代码可读性。
54 8
|
6月前
|
SQL 开发框架 前端开发
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
|
5月前
|
存储 C# 索引
C# 集合语法全解
C# 集合语法全解
41 0
|
8月前
|
C#
C#动态查询:巧用Expression组合多条件表达式
在C#中,利用`Expression`类和`AndAlso`、`OrElse`方法,可以组合两个`Expression&lt;Func&lt;T, bool&gt;&gt;`以实现动态多条件查询。该方法通过构建表达式树,方便地构建复杂查询。示例代码展示了如何创建表达式树,分别检查年龄大于等于18和姓名为&quot;John&quot;的条件,并使用`AndAlso`组合这两个条件,最终编译为可执行的委托进行测试。
324 1
|
7月前
|
开发框架 .NET 程序员
掌握C#语言的精髓:基础知识与实用技能详解(数据类型与变量+ 条件与循环+函数与模块+LINQ+异常+OOP)
掌握C#语言的精髓:基础知识与实用技能详解(数据类型与变量+ 条件与循环+函数与模块+LINQ+异常+OOP)
38 0
|
8月前
|
SQL 开发框架 .NET
C#linq表达式的应用
C#linq表达式的应用
44 0
|
2月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
42 3
|
13天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
58 12