原地址:http://blog.csdn.net/xuemoyao/article/details/8053444

 

通过上一章节的学习,相信大家已经掌握了学习LINQ的前期的准备知识。在这一节里,我会通过一些列的实例向大家讲解LINQ的语法。

在开始介绍之前,先把上节最后的一个小例子给温习下。后边的所讲的都围绕这个例子展开:

先创建一个Person类,作为数据实体

public class Person

{

public string Name

{

get;

set;

}

public string Sex

{

get;

set;

}

public int Age

{

get;

set;

}

}

List<Person> list=new List<Person>()

{

new Person(){ Name="Olive",Sex="女",Age=22},

new Person(){ Name="Moyao",Sex="男",Age=23},

new Person(){ Name="Momo",Sex="女",Age=22},

new Person(){ Name="Only",Sex="女",Age=20},

new Person(){ Name="Love",Sex="女",Age=21},

new Person(){ Name="For",Sex="女",Age=22},

new Person(){ Name="Remote",Sex="男",Age=23},

new Person(){ Name="Snow",Sex="女",Age=23}

};

/从list集合中选出性别为“女”的人

var girls = from g in list

where g.Sex== "女"

select g;

//从list集合中选出性别为“男”的人

var boys = list.Where(p => p.Sex == "男");

Console.WriteLine("Girls");

foreach (var g in girls)

{

Console.WriteLine("姓名:" + g.Name + "--性别:" + g.Sex + "--年龄:" + g.Age);

}

Console.WriteLine("Boys");

foreach (var b in boys)

{

Console.WriteLine("姓名:" + b.Name + "--性别:" + b.Sex + "--年龄:" + b.Age);

}

输出结果如下:

细心的朋友们可能会发现从list集合中获取信息的方式不一样,在获取性别为“女”的集合中采用的是from g in list where g.Sex== "女" select g;

而在获取性别为“男”的集合中采用的为list.Where(p => p.Sex == "男");

或许会有人问,这两种查询方式有什么区别呢?上面的第一种方法叫查询语法(query syntax),看上去和SQL的语句很相似。查询语法使用查询表达式书写。第二种方法叫方法语法(method syntax)是命令形式,它使用的是标准的方法调用,方法是一组叫做标准查询运算符的方法。虽然形式上这两种查询方法不同,事实上这两种方法存在着紧密的联系,在CLR内只识别查询方法,因此在每次查询的时候编译器在编译时会将查询语句翻译为查询方法,当然大部分的查询方法也都有对应的查询语句形式,例如:where对应Where(),select对应Select(),orderby对应orderby(),group对应group(),join对应Join(),distinct对应Distinct(),union对应Union(),Intersect对应Intersect(),except对应Except(),等等。

我们看SQL查询形式:select查询内容 from数据源 where查询条件,也就是分为数据源、查询条件、查询内容这三部分,在LINQ查询里也是分这三部分,从上面的例子中我们可以知道它的查询方式是这样的from a(查询内容) in数据源 where查询条件 select a(查询内容)

下边就从最基本的介绍开始。

1、from

在SQL里边from后跟的是数据源,当然在LINQ里from子句指定的也是要作为数据源使用的数据集合,但是它引入了迭代变量,迭代变量有序表示数据源的每一个元素,最后查询返回的是一个迭代变变量的集合。

2、Where/where()

在SQL里where后跟的是查询条件,在LINQ里也是一样的。

请看示例:

//查询年龄大于21且性别为女的人员的个人信息

var girls1 = from g in list

where g.Age > 21 && g.Sex == "女"

select g;

//使用查询方法查询

// var girls1 = list.Where(g => g.Age > 21 && g.Sex == "女");

Console.WriteLine("年龄大于21且性别为女的个人信息:");

foreach (var g in girls1)

{

Console.WriteLine("姓名:" + g.Name + "--性别:" + g.Sex + "--年龄:" + g.Age);

}

实验结果:

从实验结果中我们可以看到,在查询语句中where后边也可以跟一个或多个查询条件,去筛选数据,以得到想要的结果,或许还有人对使用查询方法有点疑问,查询方法where()里边的参数到底是什么呢?这里就用到了上一节我们讲的Lambda表达式。

请看Where()的原型:

where()语法是:

public static IEnumerable<TSource> where<TSource>(

this IEnumerable<TSource> source,

Func<TSource,bool> predicate)

由上一节学的知识我们可以知道该方法是一个泛型的扩展方法,该方法只接受一个Func<TSource,bool>泛型委托参数,这里的predicate是一个判断条件。

我们上边用的list.Where(g=>g.Age>21 && g.Sex) 高亮部分就相当于一个委托参数,所以用where()查询方法才能查出符合条件的信息。至于上边提到的Selec()、Orderby()等查询方法语法原型都是泛型的扩展方法和where()差不多,后边就不再过多的介绍其方法原型了。

3、select/select()

select筛选出符合条件的数据

用查询语句查询var g1=from g in list where g.Name="Olive" select g1;

用查询方法查询姓名为Olive的人员信息:

var g1 = list.Select(p=>p).Where(p=>p.Name == "Olive");

结果如下:

4、排序:orderby/OrderBy()、thenBy()、ThenByDescending()

用orderby进行排序(默认升序)

Var ps=from p in list select p orderby

用OrderBy()进行排序(升序)

var g11 = list.OrderBy(p => p.Age);

结果如图:

用orderby descending降序排列

Var ps=from p in list select p orderby p.Age descending

用OrderByDescending()降序排序

var g11 = list.OrderByDescending(p => p.Age);

结果如图:

用ThenBy()做二次排序,先按年龄的升序排序,如果年龄相等的就再按姓名升序排序

var g12 = list.OrderBy(p => p.Age).ThenBy(p => p.Name);

结果如图:

用ThenByDescending()做二次排序,先按年龄的升序排序,如果年龄相等的就再按姓名降序排序

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name);

结果如图:

5、group/GroupBy()

使用group子句可产生按照指定的键组织的组序列。

用group子句进行分组

Var ps=from p in list group p.Sex into p select p;

使用GroupBy()进行分组

var g11 = list.OrderByDescending(p => p.Age).GroupBy(p=>p.Sex);

结果如下:

6、Take、TakeWhile、Skip、SkipWhile

6.1、Take:用于从输入序列中返回指定数量的元素

//从满足条件的的序列中返回3条信息

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Take(3);

6.2、TakeWhile:只要满足一定条件的就会马上返回序列元素

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).TakeWhile(p=>p.Sex=="女");

结果如图:

6.3 、Skip:用于从输入序列中跳过指定个数的元素,返回由序列中剩余的元素所组成的新序列

//跳过4个指定元素,然后将剩余的元素组成新序列返回

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Skip(4);

6.4、SkipWhile:用于从输入序列中跳过满足一定条件指定数量的元素,返回由序列中剩余的元素所组成的新序列

//跳过姓名为“Olive”的信息,然后将剩余的的元素组成新的序列返回

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).SkipWhile(p=>p.Name=="Olive");

结果如下:

7、Count(),Max()/Min(),Average(),Sum()聚合方法

7.1、Count():统计序列中元素个数

示例:var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Count();

Console.WriteLine("总共有{0}条信息!"+g121);

结果:

7.2、Max()/Min()求最大/最小值

示例:求最大年龄:

var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Max(p => p.Age);

Console.WriteLine("最大年龄为:"+g121);

结果:

示例:求最小年龄:

var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Min(p => p.Age);

Console.WriteLine("最小年龄为:"+g121);

结果:

7.3、Average()求平均值

示例:求平均年龄:

var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Average(p => p.Age);

Console.WriteLine("平均年龄为:"+g121);

结果:

7.4、Sum()累加求和

示例:累加年龄:

var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Average(p => p.Age);

Console.WriteLine("累加年龄为:"+g121);

结果:

8、Join(),GroupJoin(),Union(),Intersect(),Except(),Contact(),Distinct操作符

8.1、Join()用于连接两个序列,和SQL里的Join语句连接多表一样,连接操作接受两个集合然后创建一个临时的对象集合,每个对象包含原始集合对象中的所有字段,使用连接来结合两个或更多个集合中的数据。

例如:这里使用上边新建的Person类,然后在新建一个Profession(职业)类

Public class Profession

{

Public string Name{get;set:}

Public string Zhiye{get;set;}

}

List<Person> list=new List<Person>()

{

new Person(){ Name="Olive",Sex="女",Age=22},

new Person(){ Name="Moyao",Sex="男",Age=23},

new Person(){ Name="Momo",Sex="女",Age=22},

new Person(){ Name="Only",Sex="女",Age=20},

new Person(){ Name="Love",Sex="女",Age=21},

new Person(){ Name="For",Sex="女",Age=22},

new Person(){ Name="Remote",Sex="男",Age=23},

new Person(){ Name="Snow",Sex="女",Age=23}

};

List<Profession> listprofession = new List<Profession>

{

new Profession() { Name = "Olive", ZhiYe = "会计" },

new Profession() { Name = "Remote", ZhiYe = "IT Coder" },

new Profession() { Name = "BLove", ZhiYe = "学生" },

new Profession(){ Name="AFor",ZhiYe="作家"}

};

使用Join查询语句查询,从Person序列和Profession序列里查询出姓名相同的信息,组合成一个新的序列,并显示姓名和职业

var showzhiye = from p in list

join pf in listprofession on p.Name equals pf.Name

select new

{

Name = p.Name,

ZhiYe = pf.ZhiYe

};

foreach (var p in showzhiye)

{

Console.WriteLine("姓名:" + p.Name + "职业:" + p.ZhiYe);

}

使用Json()方法查询:

var showzhiye = list.Join(listprofession, p => p.Name, pf => pf.Name, (p, pf) => new

{

Name = p.Name,

ZhiYe = pf.ZhiYe

});

两种方法查询的结果一样如下:

8.2、GroupJoin():将基于键相等对两个序列的元素进行关联并对结果进行分组。使用默认的相等比较器对键进行比较。

//var showzhiye = list.GroupJoin(listprofession, p => p.Name, pf => pf.Name, (p, pf) => new

{ Name = p.Name, ZhiYe = pf.Max(pf1=>pf1.Name)});

var showzhiye = listprofession.GroupJoin(list, pf => pf.Name, p => p.Name, (pf, p) => new

{

Name = pf.Name,

ZhiYe =pf.ZhiYe,

Count=p.Count()

});

结果:

8.3、Union():用于将两个输入序列中的元素合并成一个新的序列,且新序列中自动去除重复的序列

示例:List<Person> list1 = new List<Person>()

{

new Person(){ Name="Olive",Sex="女",Age=18},

new Person(){ Name="Moyao",Sex="男",Age=19},

new Person(){ Name="Momo",Sex="女",Age=20},

new Person(){ Name="Olive116",Sex="女",Age=18},

new Person(){ Name="Moyao116",Sex="男",Age=19},

new Person(){ Name="Momo116",Sex="女",Age=20},

};

var uniontest = list.Union(list1);//将list1和上边所示的list合并,自动去除重复列

foreach (var p in uniontest)

{

Console.WriteLine("姓名:" + p.Name + "年龄:"+p.Age +"性别:"+p.Sex );

}

结果:

8.4、Intersect():求两个序列的交集,将两个序列中相同的元素挑选出来组成一个新的序列

这里还是用8.3里的数据源list1、list

示例:var intersectTest = list1.Intersect(list);

foreach (var p in intersectTest)

{

Console.WriteLine("姓名:" + p.Name + "年龄:"+p.Age +"性别:"+p.Sex );

}

结果:

8.5、Except(),现有A、B两序列,返回仅在A序列中的元素所组成的序列,相当于求差集

var ExceptTest = list.Except(list1);

8.6、Contact():联接两个序列

示例:var ExceptTest = list.Concat(list1);

foreach (var p in ExceptTest)

{

Console.WriteLine("姓名:" + p.Name + "年龄:"+p.Age +"性别:"+p.Sex );

}

结果:

8.7、Distinct():检测每一个输入元素是否有相同的,如果有相同的元素则作为一个元素添加到结果序列中,相当于去除重复;

示例:list.Distinct();

【转】【收藏】LINQ学习心得分享--------(二)LINQ语法详解的更多相关文章

  1. Azure Terraform(二)语法详解

    一,引言 上篇文章开始,我们简单介绍了以下通过基础设施管理工具----- Terraform,通过它来统一管理复杂的云基础设施资源.作为入门演示,使用Terraform 部署Azure 资源组的方式直 ...

  2. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  3. 我的MYSQL学习心得(二)

    原文:我的MYSQL学习心得(二) 我的MYSQL学习心得(二) 我的MYSQL学习心得(一) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL学习心得(五) 我的MYSQL ...

  4. Java开发学习心得(二):Mybatis和Url路由

    目录 Java开发学习心得(二):Mybatis和Url路由 1.3 Mybatis 2 URL路由 2.1 @RequestMapping 2.2 @PathVariable 2.3 不同的请求类型 ...

  5. Linq实战 之 Linq to Sql及Entity Framework操作详解

    Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...

  6. Velocity魔法堂系列二:VTL语法详解

    一.前言 Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力.而且Velocity被移植到不 ...

  7. IP地址和子网划分学习笔记之《IP地址详解》

    2018-05-03 18:47:37   在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. ...

  8. Java8初体验(二)Stream语法详解(转)

    本文转自http://ifeve.com/stream/ Java8初体验(二)Stream语法详解 感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com上篇文章Java8初体验(一 ...

  9. Java8初体验(二)Stream语法详解---符合人的思维模式,数据源--》stream-->干什么事(具体怎么做,就交给Stream)--》聚合

    Function.identity()是什么? // 将Stream转换成容器或Map Stream<String> stream = Stream.of("I", & ...

随机推荐

  1. CSS常用标签

    CSS常用标签 一 CSS文字属性 color : #999999; /*文字颜色*/ font-family : 宋体,sans-serif; /*文字字体*/ font-size : 9pt; / ...

  2. 【NodeJS 学习笔记01】不学就老了

    前言 再不学nodeJs,我们就老了......在HTML5大浪袭来的时候,很多先辈就开始了NodeJs之旅,而那时我还在做服务器端的程序后来转成前端,和梯队的距离已经很大了,因为我会服务器端语言,还 ...

  3. aBowman >>可以运用到自己博客上的小插件

    大家进入我的博客会发现页面右边有一只小狗这部分.这个就是我用在上面的 一个小插件.插件网址是:http://abowman.com/google-modules/,这上面有很多的小插件,可以直接运用到 ...

  4. crm2011 使用SOAP 查询单个记录 Retrieve

    function getServiceUrl() {     var serverUrl = Xrm.Page.context.getServerUrl();     if (serverUrl.ma ...

  5. add host bat

    ::Author > mdt jindahao ::Data > @echo off title 添加记录到HOST--------Powerd by LoveQishi echo. ec ...

  6. Udp通讯(零基础)

    前面学习了Tcp通讯之后听老师同学们讲到Udp也可以通讯,实现还要跟简单,没有繁琐的连接,所以最近学习了一下,记录下来以便忘记,同时也发表出来与大家相互学习,下面是我自己写的一个聊天例子,实现了群聊私 ...

  7. RecyclerView的基本使用

    1.布局文件中使用 <android.support.v7.widget.RecyclerView android:id="@+id/recycleview" android ...

  8. 监听SD卡状态

     最近在做项目时遇到需要处理SD卡拔出时的监听,在网上找了很多资料.总结了一下, 用接收广播处理最有效率     sd卡拔插时会发送广播,具体如下(摘自一位大虾的博客  来自:http://blog. ...

  9. raw_input() 与 input() __ Python

    这两个均是 python 的内建函数,通过读取控制台的输入与用户实现交互.但他们的功能不尽相同.举两个小例子. 1 >>> raw_input_A = raw_input(" ...

  10. [转载]Emmet使用

    转载地址:http://www.iteye.com/news/27580 Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语 ...