原地址: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. JS高程2.在HTML中使用Javascript(2)

    1.延迟脚本defer 在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但是延迟执行.<script>中的脚本会延迟到浏览器遇到</html> ...

  2. windows 端口 任务

  3. iOS加密之MD5加密

    话不多说,上代码! MyMD5.h里面 #import <Foundation/Foundation.h> @interface MyMD5 : NSObject { } +(NSStri ...

  4. 让Android支持透明状态栏

    <style name="Theme.Timetodo" parent="@android:style/Theme.Holo.Light"> < ...

  5. 微信小程序之后台https域名绑定以及免费的https证书申请

    微信小程序在11月3号发布了,这是一个全新的生态,没有赶上微信公众号红利的开发者,运营者可别错过这趟车了. 但是微信的后台需要全https,之前我还不相信,后台注册了后进后台才发现,服务器配置如下图 ...

  6. Android-Using DDMS

    原文:http://developer.android.com/tools/debugging/ddms.html#how-ddms-works Android提供了一个debug工具叫做:DDMS, ...

  7. IOS开发之代理的设计小技巧

    1.关于代理对象的设计小技巧 在设计一个类,需要通过代理和协议来从外部获取需要的动态的数据.那么在这里设计使用代理会有两种方法. <第一种方法> 也是比较常见的: 在你设计的类中,声明一个 ...

  8. IOS开发之多线程 -- GCD的方方面面

    前言:这篇GCD的博文是本人阅读了很多海内外大神的关于GCD的文章,以及结合之前自己对GCD的粗浅的认识,然后取其精华,去其槽粕,综合起来的笔记,而且是尽可能的以通熟易懂的并且是正确的理论论述方式呈现 ...

  9. mac os下可能是最好的豆瓣电台——diumoo

    由于我一直用豆瓣fm听音乐,在网上找了下豆瓣的相关应用,都感觉不是太好, 最后发现一个mac版的app--diumoo! 这个软件看着非常舒服,一点也不占桌面空间,它一直默默在桌面右上角,鼠标划上去会 ...

  10. js 继承

    ECMAScript只支持实现继承(继承实际的方法),主要依靠原型链来实现. 1.原型链 基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 示例: function SuperType ...