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

一、

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

基本是对于lEnumerable 接口的扩展方法。

数组、List、Dictionary、Set... 都是实现了 lEnumerable 接口。因此都是可以使用这些扩展方法。

准备初始数据

csharp 复制代码
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}";
	}

}
csharp 复制代码
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排序

csharp 复制代码
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简化编程。

运行结果

投影

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

csharp 复制代码
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的高光时刻!

投影与匿名类型:

csharp 复制代码
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方法语法"。

还有一种"查询语法"的写法。

csharp 复制代码
var items2 = from e in list
where e.Salary>3000 orderby e.Age 
select new {e.Name,e.Age, Gender =e.Gender?"男":"女"};
相关推荐
向宇it39 分钟前
【从零开始入门unity游戏开发之——C#篇26】C#面向对象动态多态——接口(Interface)、接口里氏替换原则、密封方法(`sealed` )
java·开发语言·unity·c#·游戏引擎·里氏替换原则
Java Fans4 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手5 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
码农君莫笑5 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
鲤籽鲲6 小时前
C# Random 随机数 全面解析
android·java·c#
fkdw8 小时前
C# Newtonsoft.Json 反序列化派生类数据丢失问题
c#·json
浅尝辄止;11 小时前
C# 异步编程
c#
ou.cs14 小时前
c# 实现一个简单的异常日志记录(异常迭代+分片+定时清理)+AOP Rougamo全局注入
c#