Linq小整理
Linq(Language Integrated Query)中文翻译为语言集成查询
(1)源起
.net的设计者在类库中定义了一系列的扩展方法
来方便用户操作集合对象
这些扩展方法构成了LINQ的查询操作符
(2)使用
这一系列的扩展方法,比如:
Where,Max,Select,Sum,Any,Average,All,Concat等
都是针对IEnumerable的对象进行扩展的
也就是说,只要实现了IEnumerable接口,就可以使用这些扩展方法
1….扩展方法:
Where扩展方法:需要传入一个Func<int,bool>类型的泛型委托
这个泛型委托,需要一个int类型的输入参数和一个布尔类型的返回值
如果我们把a=>{return a>3;}这个lambda表达式传递给了Where方法
a就是int类型的输入参数,返回a是否大于3的结果
Sum扩展方法:它是计算返回集合的和;
还有其他的扩展方法(IEnumerable<T>):
Average计算平均值:Min最小元素;Max最大元素;Sum元素总和;Count元素数量;
Concat链接两个序列;相当于sql的Unoin all
Contains序列是否包含制定元素
Distinct取得序列中的非重复元素
Except获得两个序列的差集
Intersect获得两个序列的交集
First取得序列的第一个元素
将扩展方法进行分类总结:
投影类
Reverse:翻转序列中元素数据,序列.Reverse();
DefaultIfEmpty:返回指定序列的元素,如果为null为空就返回DefaultIfEmpty(指定)指定参数
Single:返回序列唯一元素,如果序列为空则返回默认值,如果序列并非包含一个元素,则会引发异常
Empty: IEnumerable<int> res = Enumerable.Empty<int>();返回一个具有指定的类型参数的空IEnumerable<T>
Range:生成指定范围内的整数的序列IEnumerable<int>res=Enumerable.Range(开始,结束);
Repeat:生成包含一个重复值得序列IEnumerable<int>res=Enumerable.Range(值,重复次数);
Select:将序列中每个元素投影到新表中
SelectMany:将序列中每个元素投影到IEnumerable<T>并将结果序列合并为一个序列
聚合计算类
Average:计算值序列的平均值;double count= IEnumerable<int>.Average();
Aggregate:Enumerable.Aggregate((a,b)=>(a+b)),对序列应用累加器函数
Count:返回序列中元素数量,int count= IEnumerable.Count();
判断类
All:确定序列中的所有元素是否满足条件 bool res= IEnumerable.All(a=>a>10);
Any:确认序列是否包含任何元素bool res= IEnumerable.Any();
Any:还可以包含条件bool res= IEnumerable.Any(a=>a>10);
Contains:通过使用默认的相等比较器确定序列是否包含制定元素bool res= IEnumerable.Contains(元素);
SequenceEqual:通过使用相应类型的默认相等比较器对序列化元素进行比较确定两个元素是否相等
bool res= IEnumerable.SequenceEqual(要比较的元素);
转换类
ToArray:从IEnumerable<T>中创建一个数组int[] res=IEnumerable.ToArray();
ToList: 从IEnumerable<T>中创建一个List<T>res=IEnumerable.ToList();
ToDictionary: 根据指定的键选择器和元素选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey, TValue>。
ToLookup: 根据指定的键选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey, TElement>。
AsEnumerable:返回类型为IEnumerable<T>的输入IEnumerable<T> res=T.AsEnumerable();
Cast<TResult>:由于Linq要针对泛型类型操作,对于非泛型的IEnumerable序列可以用Cast方法转换为泛型的序列 ArraryList l; IEnumerable<int> il=l.Cast<int>();
连接类:
Concat:链接两个序列IEnumerable res= IEnumerable.Concat(IEnumerable);
Intersect: 通过使用默认的相等比较器对值进行比较生成两个序列的交集就是把相同的值取出来
Join:基于匹配键对两个序列的元素进行关联,使用默认相等比较器进行比较
Union:通过使用默认的相等比较器生成两个序列的并集,话就是合并在一起,相等的值合并
Zip:将指定函数应用于两个序列的对应元素以生成结果序列
排序类:
OrderBy:根据键按升序对序列的元素排序
OrderByDescending:根据键按降序对序列的元素排序
ThenBy:根据某个键按升序对序列中的元素执行后续排序
ThenByDescending:根据某个键按降序对序列中的元素执行后续排序
筛选类:
First&Last:返回序列中的第一个(最后一个)元素
FirstOrDefault&LastOrDefault:返回序列中第一个(最后一个)元素,如果为空则返回默认值
Distinct:通过使用默认的相等比较器对值进行比较返回序列中的非重复元素
ElementAt:返回序列中指定索引处的元素 。IEnumerable.ElementAt(位置)比实际位置+1
ElementAtOrDefault:返回序列中指定索引处的元素,如果超出范围返回默认值
Except:通过使用默认的相等比较器对值进行比较两个序列的差集
OfType:根据指定类型筛选IEnumerable的元素
Skip:跳过序列中指定元素数量,然后返回剩余的元素
SkipWhile:只要满足指定的条件,就跳过序列中的元素返回剩余的元素
Take:从序列的开头返回指定数量的连续元素
TakeWhile:只要满足指定的条件,就会返回序列的元素
Where:基于谓词筛选值序列
分组类:
GroupBy:根据指定的键选择器函数对序列中的元素分组
GroupJoin:基于键相等对两个序列的元素进行关联并对结果进行分组,使用默认的相等比较器对键进行比较
替换:
Replace:将属性中的某个值替换为某个值例如
From a in 数据源 select a.name.replace(“被更换的值”,”要更换的值”);
截取:
Substring:将属性中值按位置截取下保存
例如:
from a in 数据源
Select new {name=a.Substring(1,2),tel=a.tel };
Linq只能用于泛型的序列,IEnumerable<T>,对于非泛型,可以用Cast或者OfType
Cast<TResult>:由于Linq要针对泛型类型操作,对于非泛型的IEnumerable序列可以用Cast方法转换为泛型的序列 ArraryList l; IEnumerable<int> il=l.Cast<int>();
OfType<TResult>:Cast会尝试将序列中所有元素都转换为TResult类型,如果待转换的非泛型序列中含有其他类型,则会报错OfType则是只将序列中调出指定类型的元素转换到泛型序列中
2….查询表达式:
LINQ查询由3基本部分组成:获取数据源,创建查询,执行查询
例如:
string[] values = { "中国", "日本", "美国", "菲律宾", "越南" };
//查询包含“国”的字符串
var valueQuery = from v in values
where v.IndexOf("国") > 0
select v;
foreach (var v in valueQuery)
{
Console.WriteLine("{0,1}", v);
}
创建一个LINQ表达式必须要以from字句开头
在这个例子中v叫做范围变量,values是数据源.v的作用域存在于当前的LINQ表达式,表达式以外不能访问这个变量,where用来筛选元素,这里的范围变量v,和foreach语句中的隐式变量v都可以由编译器推断出其类型.
(1)复合from字句
在查询数据源中,元素的属性是一个集合时,乐意使用复合from字句对这个属性集合查询,必须一个客户,可能有多个电话,就是意思是一个实体类中可能还包含另外一个实体类,可以先from一个实体类,然后在from实体类类中的参数实体类在进行where条件查询
就是 from a in 数据源1 where条件 from b in 数据源2 where条件 select new{a,b}查询出来的是由a与b组成的新值,调用的话就是var.a或var.b
(2)Into字句
Into子句提供了一个临时标识符,它存储了into子句前面的查询内容,使它后面的子句可以方便的使用,对其进行再次查询,投影等操作
应用于select group join字句中
意思就是前面查询完成的数据可以用into重新生命一个变量,into前的已完成的查询就又变成了待查询的值,into后就是要查询的条件
from a in stu
group a by a.StuId 已经查询好的数据
into b 又重新命名 成为一个新的查询
orderby b.Key descending
select b;
(3)Let子句
Let子句用于在LINQ表达式中存储子表达式的计算结果,let子句创建一个范围变量来存储结果,变量被创建后,不能修改或把其他表达式的结果重新复制给他,此范围变量可以再后续的LINQ字句中使用
意思就是在where之前可以用let新建一个临时变量储存数据源的某个值,然后可以用where来对这个let变量进行条件判断例如:
From a in 数据源 let b=数据源.值 where b=条件 select a;
(4)Join子句
如果一个数据源中元素的某个属性跟另一个数据源中的属性进行相等比较,那么这两个数据源可以用join子句进行关联,join子句用equals关键字进行比较,而不是常见的==
Join内连接
就是将两个数据源通过属性关联起来,形成一个新的序列
例如:
From a in 数据源1 join b in 数据源2 on a.属性
equals b.属性 select new {别名=a.值,别名=b.值};
join 分组链接
就是将两组数据通过属性关联然后用into形成一个新的数据源,然后new一个{}来储存想要分组的值
取里面的属性进行分组,形成一个新的序列
From a in数据源1 join b in数据源2
On a.属性 equals b.属性 into c
Select new {别名=a|b.属性,别名=c}
Join 外部链接(左外部链接)
在其中返回第一个集合的每个元素,而无论该元素在第二个集合中是否具有相关元素.就可以使用LINQ执行左通过对分组链接的结果调用方法DefaultIfEmpty<TSource>外部联接连接
就是先查询一对多中的一 然后在join多的之后将一与多关联起来:例如: a就是一,b就是多
From a in 数据源1 join b in 数据源2 on a equals b.a into c
From d in c.DefaultIfEmpty()
Select new { a.name, bname=(c==null ? String.Empty : c.name)}
(5)分组查询:
分组查询对于关系型数据库是非常常见的一种操作,在LINQ表达式中只需要使用group子句就可以轻松完成对内存对象的分组 from a in 数据源 group a by a.aa
(6)多个from字句
多个form字句查询和复合from字句从字面上看似乎一样,其实是不同的操作.复合from字句查询的是单个数据源中的子元素的集合,而多个数据源进行查询
多个from同时加上where后select可以new一个{}新的序列,可以将多个数据源存到里面,取值的话可以直接点出别名来取值
例如:
Var res=
From a in 数据源1 where a=条件
From b in 数据源2 where b=条件
Select new {a,b}
取值的话就是:res.a.属性 res.b.属性
(7)Select
最简单的select就是直接输出from子句建立的那个范围变量
From a in 数据源 select a;直接输出
也可以输入某个属性:select a.name
或者可以修改一下在输出:例如:
From a in数据源 select a.name.Replace(“小”,”大”);
Select子句可以对数据进行转换,这个过程被称为投影,select子句产生的内容取决于前面的所有子句及其自身表达式执行后的结果例如
From a in 数据源 select new {name=a.name , tel=a.tel};
就是查询出结果来以后新建一个{}把想要的值取个别名,分别保存下来
OrderBy和OrderByDescending
Orderby用于按元素的值进行升序语法为:orderby 用于排序元素的表达式
OrderByDescending用于按元素的值进行降序语法为:orderby 用于排序元素的表达式 descending
From a in 数据源 where 条件 orderby 要排序的值 (默认正序,倒叙+Descending) select a;
ThenBy和ThenByDescending
ThenBy和ThenByDescending用于对元素进行次要排序.基本语法为:
Orderby 用于排序的元素表达式(主要),用于排序的元素表达式(次要)
Orderby 用于排序的元素表达式(主要),用于排序的元素表达式(次要) descending
查询操作符表示的扩展方法来操作集合在可读性和代码的语义考虑仍有不足,于是就有了查询表达式
用法:from v in arr where v>3 select v
查询表达式总是以from字句开始,以select或者group字句结束。From字句定义了查询的范围变量(range variable),可以认为该变量是对输入序列的一个遍历,就像foreach做的那样
标准查询操作符说明:
Where
用法:arr.Where(a=>{return a>3;})
说明:找到集合中满足条件的元素
OfType
用法:arr.OfType<int>()
说明:根据指定类型,筛选集合中的元素
Select
用法:arr.Select<int,string>(a=>a.ToString());
说明:将集合中每个元素投影到新集合中.上例中新集合是一个IEnumerable<String>的集合
SelectMany
用法:arr.SelectMany<int,string>(a=>{return new List<string>(){“a”,a.ToString()};});
说明:将序列的每个元素投影到一个序列中,最终把所有序列合并
查询表达式基本字句
From:指定范围变量和数据源
Where:根据bool表达式从数据中筛选数据
Select:指定查询结果中的元素所具有的类型或表现形式
Group:对查询结果按照键值进行分组(IGrouping<TKey,TElement>)
into:提供一个标识符,他可以充当对join,group或select字句结果的引用
order by:对查询出的元素进行排序(ascending/descending)
join:按照两个指定匹配条件来Equals链接两个数据源
let:产生一个用于存储查询表达式的子表达式查询结果的范围变量