前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#进阶-LINQ表达式基础语法

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

原创
作者头像
Damon小智
发布2024-04-30 14:20:33
2360
发布2024-04-30 14:20:33
举报
文章被收录于专栏:C#全栈文档库

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


一、LINQ表达式学前准备

在学习之前,我们要做一些准备工作,我们需要创建User对象和包含User对象的集合,作为后面查询和输出的数据源。

1、C#代码准备

C#类:

代码语言:javascript
复制
class User
{
    public int id { get; set; } 
    public string name { get; set; } 
    public bool gender { get; set; }//male: true; female: fasle
    public int age { get; set; }
    public string occupation { get; set; } //职业
}
代码语言:javascript
复制
List<User> list = new List<User>()
{
    new User { id = 1, name = "Zhang Long", age = 38, gender = true, occupation = "Teacher"},
    new User { id = 2, name = "Zhang Jin", age = 18, gender = false, occupation = "Student"},
    new User { id = 3, name = "Zhang Shuai", age = 38, gender = false, occupation = "Teacher"},
    new User { id = 4, name = "Liu Guangzhi", age = 38, gender = false, occupation = "Doctor"},
    new User { id = 5, name = "Liu Ziming", age = 38, gender = true, occupation = "Doctor"},
    new User { id = 6, name = "Liu Shuai", age = 29, gender = false, occupation = "Doctor"},
    new User { id = 7, name = "Liu Jin", age = 21, gender = true, occupation = "Builder"},
    new User { id = 8, name = "Jiang Long", age = 38, gender = true, occupation = "Builder"},
    new User { id = 9, name = "Hu Ziming", age = 21, gender = true, occupation = "Student"},
    new User { id = 10, name = "Hu Jin", age = 21, gender = false, occupation = "Student"}
};

2、数据库准备

SQL数据源:


二、LINQ表达式基础语法示例

1、Select 查询

代码语言:javascript
复制
/* SQL里的表达: 查找用户里职业是医生的人的姓名,按照年龄倒序输出 */
select name from user where occupation = "Doctor" order by age desc;
代码语言:javascript
复制
/* C#版本1 */
List<string> nameList = (from u in list where u.occupation == "Doctor" orderby u.age descending select u.name).ToList();
/* C#版本2 */
List<string> nameList = list.OrderByDescending(u => u.age).Where(p => p.occupation == "Doctor").Select(x => x.name).ToList();
代码语言:javascript
复制
Liu Guangzhi, Liu Ziming, Liu Shuai /* 输出结果 */

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


2、Count 计数

代码语言:javascript
复制
/* SQL里的表达: 查找用户里姓Zhang的女性教师的数量*/
select count(*) from user where occupation = "Teacher" and name like 'Zhang%' and gender = false;
代码语言:javascript
复制
/* C#版本1 */
int count = (from u in list where u.occupation == "Teacher" where !u.gender where u.name.StartsWith("Zhang") select u).Count();
/* C#版本2 */
int count = list.Count(u => u.occupation == "Teacher" && !u.gender && u.name.StartsWith("Zhang"));
代码语言:javascript
复制
1 /* 输出结果 */

3、Average 平均值

代码语言:javascript
复制
/* SQL里的表达: 查找用户里的小于40岁的某姓医生的平均年龄 */
select avg(age) from user where occupation = "Doctor" and name like 'Liu%' and age < 40;
代码语言:javascript
复制
/* C#版本1 */
double averageNum = (from u in list where u.occupation == "Doctor" where u.age<40 where u.name.StartsWith("Liu") select u.age).Average();
/* C#版本2 */
double averageNum = list.Where(u => u.occupation == "Doctor" && u.age < 40 && u.name.StartsWith("Liu")).Select(u => u.age).Average();
代码语言:javascript
复制
35 /* 输出结果 */

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

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


5、OrderBy 排序

代码语言:javascript
复制
/* SQL里的表达: 查找用户里名字带Jin的人,优先按照年龄倒序,其次按照姓氏拼音正序,输出这些人的全部信息 */
select * from user where name like '%Jin%' order by  age desc name asc;
代码语言:javascript
复制
/* C#版本1 */

List<User> userList = (from u in list where u.name.Contains("Jin") orderby u.age descending orderby u.name select u).ToList();
/* C#版本2 */

List<User> userList = list.Where(u => u.name.Contains("Jin")).OrderByDescending(u => u.age).OrderBy(u => u.name).ToList();
代码语言:javascript
复制
{id = 10, name = Hu Jin, age = 21, gender = False, occupation = Student}, 
{id = 7, name = Liu Jin, age = 21, gender = True, occupation = Builder}, 
{id = 2, name = Zhang Jin, age = 18, gender = False, occupation = Student} /* 输出结

6、Any/All 函数

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

代码语言:javascript
复制
/* SQL里的表达: 查找用户里是否存在年龄小于30岁职业是医生的女性 */
select count(*) from user where occupation = "Doctor" and gender = false and age < 30; //返回符合的个数
代码语言:javascript
复制
/* C#版本1 */
bool result = (from u in list where u.age < 30 where !u.gender where u.occupation == "Doctor" select u).Any();
/* C#版本2 */
bool result = list.Any(u => u.age < 30 && !u.gender && u.occupation == "Doctor");

数据源中所有医生如下:

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

代码语言:javascript
复制
true /* 输出结果 */

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


7、Single/SingleOrDefault 函数

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

代码语言:javascript
复制
/* SQL里的表达: 查找用户里年龄小于30岁职业是医生的女性 */
select * from user where occupation = "Doctor" and gender = false and age < 30
代码语言:javascript
复制
/* C#版本1 */
User userResult = (from u in list where u.age < 30 where !u.gender where u.occupation == "Doctor" select u).Single();
/* C#版本2 */
User userResult = list.Single(u => u.age < 30 && !u.gender && u.occupation == "Doctor");
代码语言:javascript
复制
{id = 6, name = Liu Shuai, 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 函数

代码语言:javascript
复制
/* SQL里的表达: 查找用户表自然排序第4个人到第6个人的姓名*/
select name from user limit 3,3;
代码语言:javascript
复制
/* C#版本1 */
List<string> nameList = (from u in list select u.name).Skip(3).Take(3).ToList();
/* C#版本2 */
List<string> nameList = list.Skip(3).Take(3).Select(x => x.name).ToList();
代码语言:javascript
复制
Liu Guangzhi, Liu Ziming, Liu Shuai /* 输出结果 */

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


三、LINQ表达式总结

在现代编程中,Linq(Language Integrated Query)表达式是.NET语言中的一项强大功能,允许开发者以声明式方式查询和操作数据。Linq可以用于各种数据源,包括数组、列表、XML文件以及数据库。本部分将总结Linq的关键特性,并通过一个同类程序集的对比表格,展示Linq在不同环境下的应用与效能。

1、LINQ表达式的特点

  • 集成性:Linq表达式完美集成于C#和VB.NET等语言,提供一致的查询能力。
  • 可读性:Linq语法简洁,易于编写和理解,大大提高了代码的可读性。
  • 强类型:Linq是强类型的,这意味着在编译时就可以检查类型错误,提高程序的稳定性。
  • 多数据源支持:Linq不限于查询数据库,还可以操作数组、列表等多种数据结构。

2、LINQ与同类程序集的对比

程序集

数据源支持

性能表现

易用性评分

特点

Linq to SQL

SQL数据库

5/5

直接与SQL Server交互

Linq to XML

XML文件

4/5

简化XML数据处理

Linq to Entities

关系型和非关系型数据库

5/5

支持复杂的数据查询和操作

Linq to Objects

内存中的对象集合

5/5

适用于小型集合的快速查询


3、LINQ表达式总结

Linq技术为.NET开发者提供了一个强大的工具,能够简化复杂数据操作并整合不同的数据源。其语法的统一性和强类型特征使得开发过程中数据操作更加安全,同时也更加直观。尽管在处理非常大的数据集时性能可能会成问题,但对于大多数日常开发任务而言,Linq提供了既高效又易用的解决方案。通过使用Linq,开发者可以减少代码量,提高代码质量,并能更好地维护和扩展其应用程序。无论是在企业级应用还是在小型项目中,Linq都证明了自己的价值,是.NET生态中不可或缺的一部分。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、LINQ表达式学前准备
    • 1、C#代码准备
      • 2、数据库准备
      • 二、LINQ表达式基础语法示例
        • 1、Select 查询
          • 2、Count 计数
            • 3、Average 平均值
              • 4、Max/Min/Sum/ 最大/小值/总和
                • 5、OrderBy 排序
                  • 6、Any/All 函数
                    • 7、Single/SingleOrDefault 函数
                      • 8、Skip/Take/Top 函数
                      • 三、LINQ表达式总结
                        • 1、LINQ表达式的特点
                          • 2、LINQ与同类程序集的对比
                            • 3、LINQ表达式总结
                            相关产品与服务
                            数据库
                            云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档