原地址: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. 如何在window Form中使用Font Awesome?

    随着技术的发展,web上以前的图片按钮现在逐步换成了图标字体,这些图标字体是矢量的,矢量图意味着每个图标都能在所有大小的屏幕上完美呈现,可以随时更改大小和颜色,而且不失真,真心给人一种“高大上”的感觉 ...

  2. WPF的ComboBox 数据模板自定义

    WPF的ComboBox 有些时候不能满足用户需求,需要对数据内容和样式进行自定义,下面就简要介绍一下用数据模板(DataTemplate)的方式对ComboBox 内容进行定制: 原型设计如下: 步 ...

  3. 【再探backbone 01】模型-Model

    前言 点保存时候不注意发出来了,有需要的朋友将就看吧,还在更新...... 几个月前学习了一下backbone,这段时间也用了下,感觉之前对backbone的学习很是基础,前几天有个园友问我如何将路由 ...

  4. SAP打印机配置

    SAP打印机配置 一.SAP打印原理 SAP的打印过程分两个步骤: 1.创建假脱机请求: 2.创建输出请求: 在点击打印按钮后,系统会提示创建假脱机请求后,你可以选择直接生成输出请求,或者手动生成输出 ...

  5. Hbase Java API详解

    HBase是Hadoop的数据库,能够对大数据提供随机.实时读写访问.他是开源的,分布式的,多版本的,面向列的,存储模型. 在讲解的时候我首先给大家讲解一下HBase的整体结构,如下图: HBase ...

  6. iOS中sqlite版本号

    https://github.com/yapstudios/YapDatabase/wiki/SQLite-version-(bundled-with-OS) https://github.com/y ...

  7. iOS开发之多线程技术——NSOperation篇

    本篇将从四个方面对iOS开发中使用到的NSOperation技术进行讲解: 一.什么是NSOperation 二.我们为什么使用NSOperation 三.在实际开发中如何使用NSOperation ...

  8. Java 线程池

    系统启动一个线程的成本是比较高的,因为它涉及到与操作系统的交互,使用线程池的好处是提高性能,当系统中包含大量并发的线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系 ...

  9. 原 ng-include用法分析以及多标签页面的简单实现方式

    Demo:http://webenh.chinacloudsites.cn/Default/Demo2 在平时的项目开发中,应该会经常遇到上图所示的需求,就是在一个页面中有多个标签,被选中的标签颜色会 ...

  10. Java Se :线性表

    Java的集合框架分为两个系列,Collection和Map系列.在大学期间,学习数据结构时,好像学习了线性表.非线性表.树,哎,都给忘了.其实,在Collection系列内部又可以分为线性表.集合两 ...