目录:
- Linq
- Lambda
一.Linq
LINQ语言集成查询。为我们提供一种统一的方式来查询操作各种数据也提供了编译时类型检查和动态创建查询表达式的能力。
- 针对IEnumerable<T>对象、关系数据库、XML。
LINQ查询时有两种语法可供选择:
- 查询表达式语法
- 方法与法
1.查询表达式语法
基本语法:
from 变量 in 数据源对象 [where 条件] [group 变量 by 表达式 into 临时标识符] [orderby 表达式] select 选择列 |
示例: int[] nums = { 10, 15, 20, 25, 30 // 从数组中查询所有偶数 var result = from n in nums where n % 2 == 0 select n; |
说明:
(1)查询表达式语法与SQL(结构查询语言)语法相同。
(2)以from子句开头,以Select或GroupBy子句结束 。
(3)使用各种其他操作,如过滤,连接,分组,排序运算符以构造所需的结果。
(4)隐式类型变量 - var可以用于保存LINQ查询的结果。
查询表达式语法VS方法语法
- CRL本身只理解方法语法,由编译器将表达是语法翻译为方法语法
- 大部分方法语法都有对应的查询表达式语法
1.2Linq之查询语法
- 排序
- 合计运算符
- 查询复杂对象
- 投射:在查询中创建对象
- 多级排序
- 分组查询
- Join查询
//开头名是S的排序 var result = from n in names where n.StartsWith("s") orderby n selectn; orderby n 默认升序 orderby n descending 降序 orderby n.StartsWith(n.length-1) 按任意表达式排序 //合计运算符 var result = from n in numbers where n > 1000 select n; Console.WriteLine("大于1000的个数为:" + result.Count()); Console.WriteLine("大于1000的最大数为:" + result.Max()); Console.WriteLine("大于1000的最小数为:" + result.Min()); Console.WriteLine("大于1000的平均数为:" + result.Average()); Console.WriteLine("大于1000的数的和为:" + result.Sum(n=>(long)n)); //Sum()方法的一个重载,结果太大会溢出。 //查询复杂对象 var result = from stu in list where stu.Age == 18 select stu; //查询年龄18的 //投射 var result = from stu in list where stu.Age == 18 select new (stu.Name,stu.Age); //Linq不允许有多个字段,可创建一个新对象,来保存查询结果 Console.WriteLine("年龄为18的学员为:"); foreach (var stu in result) { Console.WriteLine(stu); } //多级排序 var result=from stu in list orderby stu.Class,stu.Age select stu.deseending; //分组查询 var result=from stu in list group stu by stu.Class into student //要计算每个组的数量,应该生成一个新的结果集student(可自定义): select new {Class=student.Key,Count=student.Count()}; var orderresult=from student in result orderby student.Count descending select student; //Join查询 var result = from stu in list join scr in Scores //一查多 on stu.ID equals scr.ID select new { stu.ID, stu.Name, scr.score }; foreach (var ss in result) { Console.WriteLine(ss); } |
2.方法语法
方法语法(也称为流利语法)主要利用System.Linq.Enumerable类中定义的扩展方法和Lambda表达式方式进行查询。
示例1:
var result = nums.Where(n => n % 2 == 0); |
2.1Linq之方法语法
2.1.1Lambda表达式
"=>"实现一个匿名方法:(参数列表)=> 语句或语句块
- 如果只有一个参数,省略()
- 可以没有参数
- 多条语句"{}"包起来
- Func<T,TResult> 委托来指定表达式返回结果类型
1.3.2 在Linq中使用Lambda表达式
- 过滤where 用来返回符合条件的子集
- 排序 调用顺序不固定
- 多级排序可以使用ThenBy()方法
- 投射 select
- Any和All
- Take 和 Skip
- First和FirstOrDefault
- Single和SingleOrDefault
- 集合方法
//过滤 var result = names.OrderBy(n => n).Where(n => n.StartsWith("s")); //多级排序 var result=list.OrderBy(stu=>stu.Class) //第一项字段必须使用OrderBy,如果是降序OrderByDescending()就要用ThenByDescending() .ThenBy(stu=>stu.Age) .ThenBy(stu=>stu.Name) .Select(stu=>new {stu.Name,stu.Age,stu.Class}); //用于方法语法的投射 //Any和All 布尔 快速确定对错 bool anyStu = list.Any(stu => stu.Sex == "男"); if (anyStu) { Console.WriteLine("学员中有男同学"); } else { Console.WriteLine("学员中没有男同学"); } bool allStu = list.All(stu => stu.Sex == "男"); if (allStu) { Console.WriteLine("学员中全部是男同学"); } else { Console.WriteLine("学员中不全是男同学"); } //Take和Skip var result = list.OrderBy(stu => stu.Age); Console.WriteLine("年龄最小的两名学员是:"); foreach (var stu in result.Take(2)) //相当于Top { Console.WriteLine(stu); } Console.WriteLine("其他学员依次为:"); foreach (var stu in result.Skip(2)) //Skip相反跳过前n个结果,返回剩余的结果 { Console.WriteLine(stu); } //First和FirstOrDefault Console.WriteLine("姓名为lisi的同学信息:"); Console.WriteLine(list.First(stu => stu.Name == "lisi")); //查询集合第一个匹配元素,没找到就返回异常 Console.WriteLine("姓名为hanjiu的同学信息:"); Console.WriteLine(list.FirstOrDefault(stu => stu.Name =="hanjiu")); //避免异常,返回空 //Single和SingleOrDefault 相当于First()和FirstOrDefault(),但是如果不止一个匹配元素则抛出异常。 //集合方法 int[] numbers = { 28, 32, 14 }; int fullCount = numbers .Count(); // 3 int digitCount = "pa55w0rd".Count(c => char.IsDigit(c)); // 3 int smallest = numbers.Min(); // 14; int largest = numbers.Max(); // 32; int smallest = numbers.Max(n => n % 10); // 8; decimal sumTotal = numbers.Sum(); // 15 decimal average = numbers.Average(); // 5 |