Linq 常用扩展方法
1、使用场景
- Linq 中提供了大量类似Where的扩展方法,简化了数据处理。
- 数组、List、Dictionary等都实现了 IEnumerable,所以都可以使用 IEnumerable扩展方法,可以使用 Linq。
- Linq中所有的扩展方法几乎都是针对IEnumerable接口的,而几乎所有能返回集合的都返回IEnumerable,所以是可以把几乎所有方法“链式使用”
2、扩展方法
- Where:查询满足条件的内容
var items1 = list.Where(e => e.Age > 30);//返回IEnumerable
- Count:查询满足条件的个数
list.Count(); list.Count(x => x.Age > 20); list.Count(x => x.Age > 20 && x.Salary > 8000);
- Any:判断是否有一条数据,返回 bool
bool a = list.Any();//true bool b = list.Any(x => x.Salary > 300000);//false
- Single:有且只有一条满足要求的数据,只能有一条,否则报错
- SingleOrDefault:最多只有一条满足要求的数据,0个或者1个,多于1个报错
- First:至少有一条,返回第一条,没有会报错
- FirstOrDefault:返回第一条或者默认值
//两种写法都行 var e1 = list.Single(x => x.Name == "Jerry"); var e2 = list.Where(x => x.Name == "Jerry").Single();
- OrderBy:正序排序
int[] nums = new int[]{3,9,6,4,10,7}; var nums = nums.OrderBy(i => i);
- OrderByDescending:倒序排序
// 根据Name的最后一个字母排序 var items1 = list.OrderByDescending(e => e.Name[e.Name.Length - 1]); // 多规则排序,后面必须使用 ThenBy var items2 = list.OrderBy(e=>e.Age).ThenBy(e=>e.Salary); var items3 = list.OrderBy(e=>e.Age).ThenByDescending(e=>e.Salary);
- Skip(n):跳过n条数据
- Take(n):获取当前内容的前三条数据
// 案例:获取从第3条开始获取3条数据 var orderedItems = list.Skip(2).Take(3); // 一页有20条数据(pageSize),当前页为第2页(Current) list.Skip(pageSize * (Current -1)).Take(pageSize);
- 聚合函数:Max()、Min()、Average()、Sum()、Count()
list.Where(e=>e.Age>30).Min(e=>e.Salary); int a = list.Max(x=>x.Age);//返回list中年龄的最大值 string s = list.Max(e=>e.Name);//字符串的大小比较
- GroupBy:参数是分组条件表达式,返回值为 IGrouping<TKey,TSource>类型的泛型 IEnumerable,也就是每一组以一个IGrouping对象的形式返回。IGrouping是一个继承自IEnumerable的接口,IGrouping中Key属性表示这一组的分组数据的值
IEnumerable<IGrouping<int,Employee>> items = list.GroupBy(x=>x.Age); foreach(IGrouping<int,Employee> g in items) { Console.WriteLine(g.Key);//g.Key为分组的条件,这里就是Age Console.WriteLine("最大工资:" + g.Max(x=>x.Salary)) foreach(Employee e in g) { Console.WriteLine(e); } Console.WriteLine("*******************"); }
- Select:把集合中的每一项转换为另外一种类型
// 只取年龄 IEnumerable<int> ages = list.Select(e=>e.Age); // 只取name var names = list.Select(e=>e.Name); // var items1 = list.Select(e=>e.Name +""+ e.Age); // var items2 = list.Where(x=>x.Age>30).Select(x=>x.Name); // 匿名类型:匿名类型在编译后,会自动生成一个类型,名字由编译器自动生成 var obj1 = new {Name="ddd",Salary=3000} Console.WriteLine(obj1.Name);//"ddd" Console.WriteLine(obj1.Salary);//3000 var items = list.Select(e=>new {XingMing = e.Name,NianLing = e.Age,Xingbie=e.Gender?"男":"女"}); foreach(var i in items) { Console.WriteLine(i.NianLing + i.XingBie); }
// 年龄分组,并获得工资的最值,以及统计人数等 public class employee { public int Age { get; set; } public int Salary { get; set; } public bool Gender { get; set; } } var list = new List<employee>(); list.Add(new employee{Age = 20,Salary =3000,Gender = true}); list.Add(new employee{Age = 20,Salary =9000,Gender = false}); list.Add(new employee{Age = 50,Salary =8000,Gender = true}); list.Add(new employee{Age = 50,Salary =1000,Gender = false }); list.Add(new employee{Age = 60,Salary =5400,Gender = true}); list.Add(new employee{Age = 60,Salary =7800,Gender = false }); list.Add(new employee{Age = 20,Salary =6700,Gender = true}); var items1 = list.GroupBy(e=>e.Age).Select(g=>new {NianLing = g.Key,MaxS = g.Max(e=>e.Salary),MinS = g.Min(e=>e.Salary),RenShu = g.Count()}); foreach(var e in items1) { Console.WriteLine(e.NianLing + "," + e.MaxS +","+ e.MinS + "," + e.RenShu); } // 结果 20,9000,3000,3 50,8000,1000,2 60,7800,5400,2
- 链式调用
IEnumerable<employee> items2 = list.Where(x=>x.Salary>5000); List<employee> list2 = items2.ToList(); employee[] array2 = items2.ToArray();
// 获取id>2的数据,然后按照Age分组,并且把分组按照Age排序,然后取出前3条,最后再投影取得年龄、人数、平均工资 var list = new List<employee>(); list.Add(new employee{ Id = 1, Age = 20,Salary =3000,Gender = true}); list.Add(new employee{ Id = 2, Age = 20,Salary =9000,Gender = false}); list.Add(new employee{ Id = 3, Age = 50,Salary =8000,Gender = true}); list.Add(new employee{ Id = 4, Age = 50,Salary =1000,Gender = false }); list.Add(new employee{ Id = 5, Age = 60,Salary =5400,Gender = true}); list.Add(new employee{ Id = 6, Age = 60,Salary =7800,Gender = false }); list.Add(new employee{ Id = 7, Age = 20,Salary =6700,Gender = true}); var result = list.Where(x => x.Id > 2).GroupBy(x => x.Age).OrderBy(x => x.Key).Take(3); //result类型:IEnumerable<IGrouping<int,employee>> var items = result.Select(x => new { NL = x.Key, RS = x.Count(), pingjun = x.Average(g => g.Salary) }); foreach (var i in items) { Console.WriteLine(i.NL + "," + i.RS +"," + i.pingjun); } //结果 20,1,6700 50,2,4500 60,2,6600