第一次接触到Linq很开心
Linq 有两种写法,一种是 语句,另一种是^表达式
linq用来遍历集合很方便,和foreach相比,在处理某些方面很有优点。比如筛选,分组...,因此 我把Linq理解成一种别样的sql,但两者的区别就像大象和故宫。
与LINQ有关的语言特性
首先呢,LINQ 要先知道 1.隐式类型,2.匿名类型,3.自动属性,4委托,5泛型,6.Lambda表达式,7.迭代器
先说一些简单的
元素操作符
这些元素操作符仅返回一个元素,不是IEnumerable。(默认值:值类型默认为0,引用类型默认为null)
1)First:返回序列中的第一个元素;如果是空序列,此方法将引发异常。
2)FirstOrDefault:返回序列中的第一个元素;如果是空序列,则返回默认值default(TSource)。
3)Last:返回序列的最后一个元素;如果是空序列,此方法将引发异常。
4)LastOrDefault:返回序列中的最后一个元素;如果是空序列,则返回默认值default(TSource)。
5)Single:返回序列的唯一元素;如果是空序列或序列包含多个元素,此方法将引发异常。
6)SingleOrDefault:返回序列中的唯一元素;如果是空序列,则返回默认值default(TSource);如果该序列包含多个元素,此方法将引发异常。
7)ElementAt:返回序列中指定索引处的元素,索引从0开始;如果索引超出范围,此方法将引发异常。
8)ElementAtOrDefault:返回序列中指定索引处的元素,索引从0开始;如果索引超出范围,则返回默认值default(TSource)。
9)Count:返回一个System.Int32,表示序列中的元素的总数量。
10)LongCount:返回一个System.Int64,表示序列中的元素的总数量。
11)Sum:计算序列中元素值的总和。
12)Max:返回序列中的最大值。
13)Min:返回序列中的最小值。
14)Average:计算序列的平均值。
这些东西我们在操作集合的时候都经常用到
1. where 筛选
List<int> intList = new List(){1, 3, 4 , 6, 8, 4};
比如筛选 大于 3 的数字
^表达式 var tmp = intList.Where(a => a >3).toList();
Linq 语句 var tmp = (from i in intList where i > 3 select i).ToList();
不加 toList() 是延迟加载的懒惰模式,否则会在遍历的时候才会有数据
OfType<int>() 可以获取所有的int类型的数据,也能和Where连用,比如
var tmp = intList.OfType<int>().Where(a => a >3).toList();
2. select 投影
将集合中的每个元素投影的新集合中。这句话的意思是说,会将筛选出来的数据放到一个新的集合 IEnumerable<T> 中比如;
IEnumerable<String> tmp = intList.Where(a => a >3).Select<int, String>(a => (a + 1).ToString());
这样 这就可以顺便理解一下为什么 不加 toList() 是延迟加载的懒惰模式,否则会在遍历的时候才会有数据
SelectMany 则是将序列的每个元素投影到一个序列中,最终把所有的序列合并 SelectMany 多出一个 合并 相当于再遍历的时候可以少一层循环
3.分组
说的再多,不如Demo
from a in scource 可以理解为 foreach (var a in scource),foreach中可以写var 也可以指定a 的类型, 这里也一样,a 前面也可以加类型
from a in scource let num = a where a > 3 &&num % 2 == 0 可以理解为 用 let 添加一些临时变量
group v by v.id into g
into 的作用呢是将前面语句的结果作为后面语句操作的数据源,g相当于拿到所有按id分组的数据
注:直接出现在join子句之后的into关键字会被翻译为GroupJoin。(into之前的查询变量可以继续使用)
而 select或group子句之后的into它会重新开始一个查询,让我们可以继续引入where, orderby和select子句,是对分步构建查询表达式的一种简写方式。(into之前的查询变量都不可再使用)
g 有key 可以查看 按什么分的组
count 是统计的个数
count(lanmud) 也可以适用,只是这样的统计是对分组之后的数据进行统计
上面的例子 是 按 v.id 分组,然后返回的分别是 id, 统计个数, 分组之后 name是小红的个数
4 排序
如果想按id 升序 可以 写成 from v in obj orderby v.id group v by v.id into g
如果想按id 降序 可以 写成 from v in OrderByDescending v.id group v by v.id into g
多个排序 用 , 隔开,
方法语句
obj.Orderby(a => a.id).ThenOrderby(a => a.name).ThenOrderByDescending(a => a.id);
Reverse()可以翻转顺序
5连接
join…in…on…equals…
指定多个数据源的关联方式
可以使用匿名类型来对多个键值进行Join,如下所示:
from x in sequenceX
join y in sequenceY on new { K1 = x.Prop1, K2 = x.Prop2 }
equals new { K1 = y.Prop3, K2 = y.Prop4 }
//等待贴代码
6.量词操作符
如果元素序列满足指定的条件,量词操作符就返回布尔值。
1)Any:确定序列是否包含任何元素;或确定序列中的任何元素是否都满足条件。
2)All:确定序列中的所有元素是否满足条件。
3)Contains:确定序列是否包含指定的元素。
例如 var tmp = (from i in intList where i > 3 select i).ToList();
tmp.Any(r => r == 3) 返回 true
tmp.All(r => r == 3) 返回 false
tmp.Contains(3) 返回 true
7.分区操作符(分页操作)
添加在查询的“最后”,返回集合的一个子集。
1)Take:从序列的开头返回指定数量的连续元素。
2)TakeWhile:只要满足指定的条件,就会返回序列的元素。
3)Skip:跳过序列中指定数量的元素,然后返回剩余的元素。
4)SkipWhile:只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素。
8.集合操作符
1)Union:并集,返回两个序列的并集,去掉重复元素。
2)Concat:并集,返回两个序列的并集。
3)Intersect:交集,返回两个序列中都有的元素,即交集。
4)Except:差集,返回只出现在一个序列中的元素,即差集。
5)Zip:通过使用指定的委托函数合并两个序列,集合的总个数不变。
6)SequenceEqual:判断两个序列是否相等,需要内容及顺序都相等。
9
小结
以上是 Linq的一个简单认识
还有很多不明白的,不会的,我会不断完善的。希望大神能指点一条进阶之路,或者谈谈感悟,不胜感激,感激不尽~
最后 感谢下某位大佬,传送门
稍等,记录一下尚且不明白的内容:
1 .会把“复合from子句”的查询表达式转换为SelectMany()扩展方法