linq的语法和案例

  本篇逐一介绍linq各个关键字的用法(from,select,group,into等),本篇所有的案例都是用linqpad来完成的(官方地址:http://www.linqpad.net/),建议想学好linq的博友们下载这个工具。

From

  查询表达式是以from开头的(之所以不延用sql的语法以'select'开头,是为了配合vs的智能语法提示)。

单个from

代码

var query = from a in new string[]{"a","b","c"}
			select a;
foreach(var item in query){
 Console.WriteLine(item);
}

结果

多个from子句执行联接

  多个from时,会对两个数据源做笛卡尔积,简单一点说,有A和B两个表,分别有x和y条记录,A和B的笛卡尔积会求出x*y条记录,即每一个A表里的一条记录对应了B表里的y条记录。可实现join语法相同的操作

示例一:

代码

var query = from a in new string[]{"a","b","c"}
			from b in new int[]{1,2,3}
			select new{A=a,B=b};
foreach(var item in query){
 Console.WriteLine(item.A+" "+item.B);
}

  结果

  当然,可以再对上面的笛卡尔积做where的条件筛选操作,这样就会求出自己想要的记录。

复合from子句

  上一个示例只是简单的多个from的联接,如果下一个from子句的数据源和上一个from对象有联系时,就要用到复合from子句,但语法是一样的

代码

from a in new List<(string name,string[] scores)>{
        {("张三",new string[]{"80","90"})},
        {("李四",new string[]{"30","40"})}
        }
from b in a.scores  
select new {a,b}

 

结果的结构

 

where

   where 子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的哪些元素。 它将一个布尔条件(谓词)应用于每个源元素(由范围变量引用),并返回满足指定条件的元素。 一个查询表达式可以包含多个 where子句,一个子句可以包含多个谓词子表达式

如下面的两个查询表达式是一样的

from a in new int[]{1,2,3,4,5}
where a>1 && a<4
select a

from a in new int[]{1,2,3,4,5}
where a>1
where a<4
select a

 

select

  select用于生成要返回的结果,可做为查询表达式的结尾(必须以select或是group结尾)。

返回结果为旧类型

  可参考from一节里的“单个from”案例,select语法没有new关键字,以之前的类型为返回

返回结果为新类型

  可参考from一节里的“多个from”案例,select语法后跟了new关键字,会以new的匿名类型做为新的返回类型。下面将代码稍做改动,变于查看每个结果记录的结构。

代码:

var query = from a in new string[]{"a","b","c"}
			from b in new int[]{1,2,3}
			select new{FieldOfA=a,FieldOfB=b};
foreach(var item in query){
 //Console.WriteLine(item.A+" "+item.B);
 Console.WriteLine(item);
}

结果

 

排序

有升序:orderby,thenby

降序:OrderByDescending,ThenByDescending

var list=new List<string[]>{
new string[3]{"学校1","1年级","班级1"},
new string[3]{"学校1","1年级","班级2"},
new string[3]{"学校1","2年级","班级1"},
new string[3]{"学校1","2年级","班级2"},
new string[3]{"学校2","1年级","班级1"},
new string[3]{"学校2","1年级","班级2"},
new string[3]{"学校2","2年级","班级1"},
new string[3]{"学校2","2年级","班级2"}
};
var query1=list.OrderBy(a=>a[0]).ThenByDescending(a=>a[1]).ThenBy(a=>a[2]).Select(a=>a);
var query2 = from a in list
			orderby a[0],a[1] descending,a[2]
			select a;
foreach(var item in query1){
Console.WriteLine($"{item[0]}--{item[1]}--{item[2]}");
}

foreach(var item in query2){
Console.WriteLine($"{item[0]}--{item[1]}--{item[2]}");
}

  的查询表达式里只有orderby,配合descending来使用。

 

group

  1))语法上:可以以group作为查询表达式的结尾(如from a in tab_a group a by a.xxx),但如果group后跟了into,必须继续编写该查询,并最终使用一个select 语句或另一个 group子句结束该查询

  2)返回的类型:返回一个 IGrouping<TKey,TElement> 对象序列,TKey的类型为by关键字后面的类型,TElement的类型为group关键字后面的类型

  3)分组键的类型:组键可以是任何类型,如字符串、内置数值类型、用户定义的命名类型或匿名类型。分组键即by关键字后的对象

以单个键为分组键

示例

from a in new List<string>{"aa","aa","ab","ab","ba","ba","bb","bb"}
group a by a[0]

 

以组合键为分组键

示例

from a in new List<string>{"aa1","aa2","ab1","ab2"}
group a by new{first=a[0],second=a[1]}

 

以布尔值为分组键

示例

from a in new List<string>{"a","ab","abc","abcd"}
group a by a.Length>2

 

返回类型里的元素类型

  group返回的类型为 IGrouping<TKey,TElement>,TKey的类型由by关键字后面的类型决定;而TElement的类型则于group关键字后面的类型决定。

示例1

from a in new List<string>{"aa1","aa2","ab1","ab2"}
group new{firstChar=a[0],secondChar=a[1],thirdChar=a[2] } by new{first=a[0],second=a[1]}

示例二

from a in new List<string>{"张三","李四"}
join b in new List<string[]>{
                new string[]{"张三","英语","60"},
                new string[]{"张三","语文","70"},
                new string[]{"李四","英语","90"},
                new string[]{"李四","语文","80"},
                }
    on a equals b[0]
group new {姓名=a,学科=b[1],成绩=b[2]} by a

 

posted @ 2018-01-30 11:42  shengyu_kmust  阅读(602)  评论(0编辑  收藏  举报