杨中科 .netcore Linq常用的扩展方法

发布于:2024-10-12 ⋅ 阅读:(7) ⋅ 点赞:(0)

一、

LINQ中提供了大量类似Where的扩展方法,简化数据处理。大部分都在System.Linq命名空间中

基本是对于lEnumerable 接口的扩展方法。
数组、List、Dictionary、Set… 都是实现了 lEnumerable 接口。因此都是可以使用这些扩展方法。

准备初始数据

class Employee
{
	public long ld { get; set; }
	public string Name {get; set; }//姓名
	public int Age {get; set; }//年龄
	public bool Gender {get; set; }//性别
	public int Salary{get; set; }//月薪
	public override string ToString()
	{
		return
		$"ld={ld},Name={Name},Age={Age},Gender={Gender},Salary={Salary}";
	}

}

List<Employee> list = new List<Employee>;
list.Add(new Employee {ld = 1, Name = "jerry", Age = 28, Gender = true, Salary = 5000 });
list.Add(new Employee {ld = 2, Name = "jim", Age = 33, Gender = true, Salary = 3000 });
list.Add(new Employee { ld = 3, Name = "lily", Age = 35, Gender = false, Salary = 9000 });
list.Add(new Employee {ld =4, Name ="lucy",Age = 16, Gender = false, Salary= 2000 });
list.Add(new Employee {ld=5,Name = "kimi",Age = 25,Gender = true, Salary = 1000 });
list.Add(new Employee {ld =6, Name = "nancy", Age = 35, Gender = false, Salary = 8000 });
list.Add(new Employee {ld=7,Name = "zack", Age = 35, Gender = true, Salary = 8500 });
list.Add(new Employee {ld = 8, Name = "jack", Age = 33, Gender = true, Salary = 8000 });

where 方法

Where方法:每一项数据都会经过predicate的测试,如果针对一个元素,predicate执行的返回值为true,那么这个元素就会放到返回值中。

Where参数是一个lambda表达式格式的匿名方法,方法的参数e表示当前判断的元素对象。参数的名字不一定非要叫e,不过一般lambda表达式中的变量名长度都不长。

传入一个过滤的lambda 表达式
在这里插入图片描述

source对哪个数据做过率,predicate 泛型委托(Tsource是传入数据类型,返回值是bool。判断参数是否满足过滤条件)

在这里插入图片描述

示例:

过滤年龄大于三十
在这里插入图片描述
运行结果

在这里插入图片描述

Count()方法

:获取数据条数
int count1 = list.Count(e =>e.Salary>5000 || e.Age < 30);
int count2 = list.Where(e =>e.Salary> 5000 || e.Age <30).Count();

源码:
在这里插入图片描述

示例:

在这里插入图片描述
运行结果
在这里插入图片描述

Any()方法

:是否至少有一条数据满足条件
bool b1 = list.Any(e => e.Salary >8000);
bool b2 = list.Where(e =>e.Salary>8000).Any();
有可能比Count()实现效率高。any()获取到一条满足条件的数据就不会继续往下寻找。count需要查找所有满足条件的数据。

示例

在这里插入图片描述

获取一条数据(是否带参数的两种写法)

Single:有且只有一条满足要求的数据;

多条、一条满足条件的数据都没有,会抛出异常

示例:
在这里插入图片描述

运行结果:报错,这么序列中,含有多于一条数据。

在这里插入图片描述

示例2:取出只有一个满足条件的数据
在这里插入图片描述

运行结果
在这里插入图片描述

示例3: 没有匹配结果,和直接在single中传入条件
在这里插入图片描述

运行结果:报错,没有匹配的元素
在这里插入图片描述

SingleOrDefault :最多只有一条满足要求的数据;

多条满足条件数据,会抛出异常。没有则返回默认值(int 0,string null)

示例1:有一条数据满足条件

在这里插入图片描述
运行结果

在这里插入图片描述
示例2:一条满足条件的数据都没有的情况,返回默认值

在这里插入图片描述
运行结果
在这里插入图片描述

First :至少有一条,返回第一条;

多条返回第一条,一条没有会抛出异常

示例1:多条返回第一条
在这里插入图片描述

运行结果:
在这里插入图片描述
示例2:一个都没有的情况
在这里插入图片描述

运行结果:抛出异常
在这里插入图片描述

FirstOrDefault :返回第一条或者默认值

返回一条,一条都没有就返回默认值

选择合适的方法,“防御性编程”

排序:

Order()对数据正序排序;

list.OrderBy(e => e.Age);

示例:根据age 排序
在这里插入图片描述
运行结果:
在这里插入图片描述

OrderByDescending()倒序排序;

示例:
在这里插入图片描述

运行结果
在这里插入图片描述

对于简单类型排序

示例:根据自己排序
在这里插入图片描述
运行结果:
在这里插入图片描述

特殊案例: 按照最后一个字符排序;
在这里插入图片描述

运行结果:
在这里插入图片描述

用Guid或者随机数进行随机排序。
在这里插入图片描述

多规则排序

可以在Order()、OrderByDescending()后继续写ThenBy()、ThenByDescending().
案例:优先按照Age排序,如果Age相同再按照Salary排序

list.OrderBy(e =>e.Age).ThenByDescending(e>e.Salary)

千万不要写成
list.OrderBy(e => e.Age).OrderByDescending(e =>e.Salary)

示例

在这里插入图片描述
运行结果
在这里插入图片描述

连续使用两次orderby,导致排序混乱
在这里插入图片描述

限制结果集,获取部分数据

:Skip(n)跳过n条数据,Take(n)获取n条数据。

案例:获取从第2条开始获取3条数据var orderedltems1 = list.Skip(2).Take(3)
Skip()、Take()也可以单独使用。

示例

在这里插入图片描述

运行结果:
在这里插入图片描述

聚合函数

:Max()、Min()、Average()、sum()、Count ().

LINQ中所有的扩展方法几乎都是针对IEnumerable接口的,而几乎所有能返回集合的都返回lEnumerable,所以是可以把几乎所有方法“链式使用”的。list.Where(e =>e.Age > 30).Min(e=>e.Salary)

示例:

在这里插入图片描述

年龄大于30,平均工资
在这里插入图片描述

分组:

GroupBy()方法参数是分组条件表达式,返回值为lGrouping<TKey,Tsource>类型的泛型IEnumerable,也就是每一组以一个IGrouping对象的形式返回。
lGrouping是一个继承自lEnumerable的接口,IGrouping中Key属性表示这一组的分组数据的值。

根据年龄分组
在这里插入图片描述

运行结果
在这里插入图片描述

例子:根据年龄分组,获取每组人数、最高工资、平均工资。用var简化编程。
在这里插入图片描述

运行结果
在这里插入图片描述

投影

把集合中的每一项转换为另外一种类型

lEnumerable<int> ages = list.Select(e =>e.Age);

lEnumerable<string> names =list.Select(e=>e.Gender?"男":"女");

var dogs = list.Select(p=>newDog{NickName=e.Name,Age=e.Age});

示例:

在这里插入图片描述

运行结果
在这里插入图片描述

匿名类型:

var p = new {Name=“tom”,ld=1}
var p1 = new {name,ld=1,p.Age};

编译时,创建了一个匿名类型
在这里插入图片描述

通过反编译看匿名类型原理。
在这里插入图片描述
匿名类型,是编译器为我们生成的类型

var的高光时刻!

投影与匿名类型:

var items= list.Select(e=>new{e.Name,e.Age,XingBie=e.Gender?"男":'女"});

var items = list.GroupBy(e =>e.Gender)
.Select(g=>new{ 
				Gender=g.Key,
				Count=g.Count(),
				AvgSalary=g.Average(e => e.Salary),
				MinAge= g.Min(e =>e.Age)
				}
);

集合转换

:有一些地方需要数组类型或者List类型的变量,我们可以用ToArray()方法和ToList()分别把IEnumerable转换为数组类型和List类型

示例

在这里插入图片描述

链式调用

Where、Select、OrderBy、 GroupBy、Take、skip等返回值都是lEnumerable类型,所以可以链式调用。

例子:“获取ld>2的数据,然后按照Age分组,并且把分组按照Age排序然后取出前3条,最后再投影取得年龄人数、平均工资
在这里插入图片描述

查询语法

使用Where、OrderBy、Select等 扩展方法进行数据查询的写法叫做“LINQ方法语法”。
还有一种“查询语法”的写法。

var items2 = from e in list
where e.Salary>3000 orderby e.Age 
select new {e.Name,e.Age, Gender =e.Gender?"男":"女"};