c#提供的ling查询极大的遍历了集合的查询过程,且使用简单方便,非常的有用。

下面将分别用简单的例子说明:ling基本查询、延迟查询属性、类型筛选、复合from字句、多级排序、分组查询、联合查询、合并、分页、聚合操作符、并行linq、取消长时间运行的并行ling查询。

Lambda表达式简介:

 /*Lambda表达式:Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数
表达式位于 => 运算符右侧的 lambda 表达式称为“表达式 lambda”。
* (input parameters) => expression
* 示例:*/
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(); //最后j = 25
}
  • 基本查询

语句:

 var query = from r in listStudents where r.score <  orderby r.score descending select r;
//var q2 = listStudents.Where(r => r.score < 60).OrderByDescending(r => r.score).Select(r => r) ;//或使用Lambda表达式

例子:

 /// <summary>
/// 学生结构体
/// </summary>
struct Student
{
/// <summary>
/// 姓名
/// </summary>
public string name;
/// <summary>
/// 年龄
/// </summary>
public int age;
/// <summary>
/// 班号
/// </summary>
public int grade;
/// <summary>
/// 分数
/// </summary>
public float score;
}
/// <summary>
/// linq
/// 基本查询
/// </summary>
static void Linq1()
{
#region 构造查询数据
List<Student> listStudents = new List<Student>();
Random pRandom = new Random();
for (int i = ; i < ; i++)
{
float sc = pRandom.Next(, );
int age = pRandom.Next(, );
int gde = pRandom.Next(, ); string name = "";
switch (pRandom.Next(, ))
{
case : name = "周xxx"; break;
case : name = "李xxx"; break;
case : name = "孙xxx"; break;
case : name = "钱xxx"; break;
default: name = "赵xxx"; break;
} Student psdt = new Student();
psdt.name = name;
psdt.age = age;
psdt.grade = gde;
psdt.score = sc;
listStudents.Add(psdt);
}
#endregion
//从50个学生中选择出不及格的人员名单并按分数降序排列
var query = from r in listStudents where r.score < orderby r.score descending select r;
//var q2 = listStudents.Where(r => r.score < 60).OrderByDescending(r => r.score).Select(r => r) ;//或使用Lambda表达式
//orderby升序即从小到大,orderby r.score descending降序即从大到小 Console.WriteLine("不及格的人员名单:");
foreach (Student st in query)
{
Console.WriteLine("***************");
Console.WriteLine("姓名:"+st.name);
Console.WriteLine("班级:"+st.grade);
Console.WriteLine("年龄:"+st.age);
Console.WriteLine("分数:"+st.score);
}
Console.ReadKey();
}
  • 延迟查询属性

linq查询为延迟查询,只需构造一次查询语句,可以多次使用。

例子:

/// <summary>
/// Linq
/// 延迟查询
/// linq查询为延迟查询,只需构造一次查询语句,可以多次使用
/// </summary>
static void Linq2()
{
#region 构造查询数据
List<string> lists = new List<string> { "Jack","Pet","Hant","Li","Kkk"}; #endregion
var query = from r in lists where r.StartsWith("J") select r;
Console.WriteLine("第一次查询结果:");
foreach (string st in query)
{
Console.WriteLine( st);
} Console.WriteLine("第二次查询结果:");
lists.Add("Jone");
lists.Add("Jimi");
lists.Add("Johu");
foreach (string st in query)
{
Console.WriteLine(st);
} Console.ReadKey();
/*
输出结果:
* 第一次:Jack
* 第二次:Jack Jone Jimi Johu
*/
}
  • 类型筛选

利用OfType方法可以把特定类型数据筛选出来。

例子:

 /// <summary>
/// Linq类型筛选-ofType
/// </summary>
static void Linq3()
{
object[] pList = new object[] { ,"one",,"two",,"three"};
var query = pList.OfType<string>();
foreach (var st in query)
{
Console.WriteLine(st);
}
Console.ReadKey();
/*
输出结果:
* one two three
*/
}
  • 复合from子句

语句:

 var query = from s in listStudents
from n in s.name
where n == '赵' orderby s.score descending
select s.grade + "班-" + s.name + ",分数" + +s.score;
/*查询出所有姓赵的学生的班级、姓名、分数信息,并按分数由高到低排序*/

例子:

 /// <summary>
/// linq复合from字句
/// </summary>
static void Linq4()
{
#region 构造查询数据
List<Student> listStudents = new List<Student>();
Random pRandom = new Random();
for (int i = ; i < ; i++)
{
float sc = pRandom.Next(, );
int age = pRandom.Next(, );
int gde = pRandom.Next(, ); string name = "";
switch (pRandom.Next(, ))
{
case : name = "周xxx"; break;
case : name = "李xxx"; break;
case : name = "孙xxx"; break;
case : name = "钱xxx"; break;
default: name = "赵xxx"; break;
} Student psdt = new Student();
psdt.name = name;
psdt.age = age;
psdt.grade = gde;
psdt.score = sc;
listStudents.Add(psdt);
}
#endregion
var query = from s in listStudents
from n in s.name
where n == '赵' orderby s.score descending
select s.grade + "班-" + s.name + ",分数" + +s.score;
/*查询出所有姓赵的学生的班级、姓名、分数信息,并按分数由高到低排序*/
foreach (var t in query)
{
Console.WriteLine(t);
}
Console.ReadKey();
}
  • 多级排序

语句:

 //参数越靠前,优先级越高
//先按score排序,当分数相同时再按grade排序...依次类推
var query = from s in listStudents orderby s.score, s.grade, s.age, s.name select s;

例子:

 /// <summary>
/// 多级排序
/// </summary>
static void Linq5()
{
#region 构造查询数据
List<Student> listStudents = new List<Student>();
Random pRandom = new Random();
for (int i = ; i < ; i++)
{
float sc = pRandom.Next(, );
int age = pRandom.Next(, );
int gde = pRandom.Next(, ); string name = "";
switch (pRandom.Next(, ))
{
case : name = "周xxx"; break;
case : name = "李xxx"; break;
case : name = "孙xxx"; break;
case : name = "钱xxx"; break;
default: name = "赵xxx"; break;
} Student psdt = new Student();
psdt.name = name;
psdt.age = age;
psdt.grade = gde;
psdt.score = sc;
listStudents.Add(psdt);
}
#endregion
//参数越靠前,优先级越高
//先按score排序,当分数相同时再按grade排序...依次类推
var query = from s in listStudents orderby s.score, s.grade, s.age, s.name select s;
foreach (Student st in query)
{
Console.WriteLine("***************");
Console.WriteLine("姓名:" + st.name);
Console.WriteLine("班级:" + st.grade);
Console.WriteLine("年龄:" + st.age);
Console.WriteLine("分数:" + st.score);
}
Console.ReadKey();
}
  • 分组

语句:

 //按国家分组,并选出大于2的组,形成新的集合
var query = from r in listChampion
group r by r.country into g
orderby g.Count() descending, g.Key
where g.Count() >=
select
new { country = g.Key, count = g.Count() };

例子:

 /// <summary>
/// 分组
/// </summary>
static void Linq6()
{
List<Champions> listChampion = new List<Champions>();
listChampion.Add(new Champions() { name = "张**", country = "中国" });
listChampion.Add(new Champions() { name = "赵**", country = "中国" });
listChampion.Add(new Champions() { name = "李**", country = "中国" });
listChampion.Add(new Champions() { name = "李**", country = "中国" });
listChampion.Add(new Champions() { name = "Peter", country = "美国" });
listChampion.Add(new Champions() { name = "Hune", country = "美国" });
listChampion.Add(new Champions() { name = "Hune", country = "美国" });
listChampion.Add(new Champions() { name = "Jack", country = "俄罗斯" });
listChampion.Add(new Champions() { name = "Jack", country = "俄罗斯" });
listChampion.Add(new Champions() { name = "Jimi", country = "英国" });
//按国家分组,并选出大于2的组,形成新的集合
var query = from r in listChampion
group r by r.country into g
orderby g.Count() descending, g.Key
where g.Count() >=
select
new { country = g.Key, count = g.Count() };
foreach (var o in query)
{
Console.WriteLine("国家:{0},冠军数:{1}个", o.country, o.count);
}
Console.ReadKey();
}
  • 联合查询-join

语句:

 //查询出集合qSt中year等于集合qSc中year的元素并形成新的集合
var qjoin = from r in qSt
join c in qSc
on r.year equals c.year
select new
{
Year = r.year,
stName = r.name,
scName = c.name
};

例子:

  /// <summary>
/// 联合查询-join
/// </summary>
static void Linq7()
{
List<s> pSt = new List<s>();
pSt.Add(new s() {year=,name="xxx" });
pSt.Add(new s() { year = , name = "xxx" });
pSt.Add(new s() { year = , name = "xxx" });
pSt.Add(new s() { year = , name = "xxx" });
List<school> pSc = new List<school>();
pSc.Add(new school() { year = , name = "***" });
pSc.Add(new school() { year = , name = "***" });
pSc.Add(new school() { year = , name = "***" });
pSc.Add(new school() { year = , name = "***" });
pSc.Add(new school() { year = , name = "***" }); var qSt = from r in pSt where r.year >= select r;
var qSc = from r in pSc where r.year >= select r; //查询出集合qSt中year等于集合qSc中year的元素并形成新的集合
var qjoin = from r in qSt
join c in qSc
on r.year equals c.year
select new
{
Year = r.year,
stName = r.name,
scName = c.name
}; foreach (var ite in qjoin)
{
Console.WriteLine(ite.Year + " " + ite.scName + " " + ite.stName);
Console.WriteLine("");
}
Console.ReadKey();
}
  • 合并-zip()

.Net4.0新增,可对两个相关的序列进行合并。

语句:

  /*若合并两项项数不同,则在达到较小集合的末尾时停止*/
var qZip = qSc.Zip(qSt, (first, second) =>string.Format("Year:{0},Name:{1}.", first.Year,second.Name));//返回值qZip为字符串集合

例子:

 /// <summary>
/// 合并-zip()-.Net4.0新增,可对两个相关的序列进行合并
/// </summary>
static void Linq8()
{
List<s> pSt = new List<s>();
pSt.Add(new s() { year = , name = "一xxx" });
pSt.Add(new s() { year = , name = "二xxx" });
pSt.Add(new s() { year = , name = "三xxx" });
pSt.Add(new s() { year = , name = "四xxx" });
pSt.Add(new s() { year = , name = "五xxx" });
List<school> pSc = new List<school>();
pSc.Add(new school() { year = , name = "1***" });
pSc.Add(new school() { year = , name = "2***" });
pSc.Add(new school() { year = , name = "3***" });
pSc.Add(new school() { year = , name = "4***" });
pSc.Add(new school() { year = , name = "5***" }); var qSt = from r in pSt where r.year >= orderby r.year select new { Year = r.year, Name = r.name };
var qSc = from r in pSc where r.year >= orderby r.year select new { Year = r.year, Name = r.name };
/*若合并两项项数不同,则在达到较小集合的末尾时停止*/
var qZip = qSc.Zip(qSt, (first, second) =>string.Format("Year:{0},Name:{1}.", first.Year,second.Name));//返回值qZip为字符串集合 foreach (var ite in qZip)
{
Console.WriteLine(ite);
}
Console.ReadKey(); }
  • 分区(分页)

通过Take()和Skip()实现只显示部分查询结果。

语句:

 //通过skip跳过指定数量的元素,再通过take提取固定长度元素,可实现分页
var qr = (from r in listStudents orderby r.score descending select r).Skip(i * pageSize).Take();
//var qr2 = listStudents.OrderByDescending(r => r.score).Select(r => r).Skip(i * pageSize).Take(5);//或

例子

 /// <summary>
/// 分区(分页)-通过Take()和Skip()实现只显示部分查询结果
/// </summary>
static void Linq9()
{
#region 构造查询数据
List<Student> listStudents = new List<Student>();
Random pRandom = new Random();
for (int i = ; i < ; i++)
{
float sc = pRandom.Next(, );
int age = pRandom.Next(, );
int gde = pRandom.Next(, ); string name = "";
switch (pRandom.Next(, ))
{
case : name = "周xxx"; break;
case : name = "李xxx"; break;
case : name = "孙xxx"; break;
case : name = "钱xxx"; break;
default: name = "赵xxx"; break;
} Student psdt = new Student();
psdt.name = name;
psdt.age = age;
psdt.grade = gde;
psdt.score = sc;
listStudents.Add(psdt);
}
#endregion int pageSize = ;
int numofPage = (int)Math.Ceiling(listStudents.Count /(double)pageSize); for (int i = ; i < numofPage; i++)
{
Console.WriteLine("第{0}页", i); //通过skip跳过指定数量的元素,再通过take提取固定长度元素,可实现分页
var qr = (from r in listStudents orderby r.score descending select r).Skip(i * pageSize).Take();
//var qr2 = listStudents.OrderByDescending(r => r.score).Select(r => r).Skip(i * pageSize).Take(5);//或
foreach (var ite in qr)
{
Console.WriteLine(ite.name);
Console.WriteLine(ite.score);
}
Console.WriteLine("");
}
Console.ReadKey();
}
  • 并行linq

并行查询可以分解查询的工作,使其分布在多个线程上。当pc拥有多个cpu时,可以看到并行查询带来的改进效果。并行LINQ适用于大型的集合查询,并拥有一定的优势。使用

System.Collections.Concurrent.Partitioner.Create
可以手动创建分区器。

语法:

var sum2 = (from x2 in data.AsParallel() where x2 >  select x2).Sum();//并行查询

//var sum3 = data.AsParallel().Where(x3 => x3 > 20).Sum();//或并行查询(Lambda表达式)

例子:

 /// <summary>
/// 并行linq
/// </summary>
static void Linq11()
{
Console.WriteLine("开始构造大数组...");
//构造大数组
const int count = ;
var data = new int[count];
var r = new Random();
for (int i = ; i < count; i++)
{
data[i] = r.Next();
}
Console.WriteLine("开始计算...");
var st = System.DateTime.Now;
var sum = (from x in data where x > select x).Sum();//常规linq-耗时1.8641s
var st2 = System.DateTime.Now;
var sum2 = (from x2 in data.AsParallel() where x2 > select x2).Sum();//并行查询-耗时0.6620s //var sum3 = data.AsParallel().Where(x3 => x3 > 20).Sum();//或并行查询----x3 => x3 > 20(Lambda表达式)
var st3 = System.DateTime.Now; /*Partitioner.Create
手动创建分区器
* Create具有多个重载,可依据需求进行分区
*/
var sum4 = (from c in System.Collections.Concurrent.Partitioner.Create(data, true).AsParallel() where c > select c).Sum(); var dt1 = st2 - st;
var dt2 = st3 - st2;
Console.WriteLine("常规linq耗时:{0}s",dt1.TotalSeconds.ToString());
Console.WriteLine("并行linq耗时:{0}s", dt2.TotalSeconds.ToString());
Console.ReadKey();
}

输出结果:

可以粗鲁的认为并行linq对于大集合的查询是优势比较明显的。

  • 取消长时间运行的并行linq查询

对于并行ling而言,可以设置可以利用System.Threading.CancellationTokenSource设置取消操作。

语法:

 //通过.WithCancellation(cts.Token)设置
var sum = (from x in data.AsParallel().WithCancellation(cts.Token) where x < select x).Average();

例子:

 /// <summary>
/// 取消长时间运行的并行linq查询
/// </summary>
static void Linq12()
{
//构造大数组
const int count = ;
var data = new int[count];
var r = new Random();
for (int i = ; i < count; i++)
{
data[i] = r.Next();
} var cts = new System.Threading.CancellationTokenSource(); new System.Threading.Thread(() =>
{
try
{
//通过.WithCancellation(cts.Token)设置
var sum = (from x in data.AsParallel().WithCancellation(cts.Token) where x < select x).Average();
Console.WriteLine("sum:{0}", sum);
}
catch(OperationCanceledException ex)
{
Console.WriteLine(ex.Message);
}
}).Start(); Console.WriteLine("计算开始...");
Console.WriteLine("取消请按n!");
var rk = Console.Read();
if(rk=='n'||rk=='N')
{
cts.Cancel();
} }

至此,对于LINQ已经有了一个基本的了解。

c# Linq查询的更多相关文章

  1. Entity Framework 6 Recipes 2nd Edition(13-6)译 -> 自动编译的LINQ查询

    问题 你想为多次用到的查询提高性能,而且你不想添加额外的编码或配置. 解决方案 假设你有如Figure 13-8 所示的模型 Figure 13-8. A model with an Associat ...

  2. LinqToDB 源码分析——轻谈Linq查询

    LinqToDB框架最大的优势应该是实现了对Linq的支持.如果少了这一个功能相信他在使用上的快感会少了一个层次.本来笔者想要直接讲解LinqToDB框架是如何实现对Linq的支持.写到一半的时候却发 ...

  3. Linq查询基本操作

    摘要:本文介绍Linq查询基本操作(查询关键字) - from 子句 - where 子句 - select子句 - group 子句 - into 子句 - orderby 子句 - join 子句 ...

  4. C#基础:LINQ 查询函数整理

    1.LINQ 函数   1.1.查询结果过滤 :where() Enumerable.Where() 是LINQ 中使用最多的函数,大多数都要针对集合对象进行过滤,因此Where()在LINQ 的操作 ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (26) ------ 第五章 加载实体和导航属性之延缓加载关联实体和在别的LINQ查询操作中使用Include()方法

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-7  在别的LINQ查询操作中使用Include()方法 问题 你有一个LINQ ...

  6. Rafy 中的 Linq 查询支持(根据聚合子条件查询聚合父)

    为了提高开发者的易用性,Rafy 领域实体框架在很早开始就已经支持使用 Linq 语法来查询实体了.但是只支持了一些简单的.常用的条件查询,支持的力度很有限.特别是遇到对聚合对象的查询时,就不能再使用 ...

  7. Linq查询表达式

    目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...

  8. .NET LINQ查询操作中的类型关系

    LINQ 查询操作中的类型关系      若要有效编写查询,您应该了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果您了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. 另外 ...

  9. .NET LINQ查询语法与方法语法

    LINQ 查询语法与方法语法      通过使用 C# 3.0 中引入的声明性查询语法,介绍性 LINQ 文档中的多数查询都被编写为查询表达式. 但是,.NET 公共语言运行时 (CLR) 本身并不具 ...

随机推荐

  1. 处理Xcode 警告

    除了代码中我们手动加入的 #Waring  标示 所产生的警告,我们都应该重视.下面是一些警告的处理. 1,方法过期,或 使用新的api  替换方案 multipartFormRequestWithM ...

  2. Ubuntu14.04 Django Mysql安装部署全过程

    Ubuntu14.04 Django Mysql安装部署全过程   一.简要步骤.(阿里云Ubuntu14.04) Python安装 Django Mysql的安装与配置 记录一下我的部署过程,也方便 ...

  3. 敏捷开发与jira之阶段工作项概述

    每次迭代都分这5个阶段,但每个阶段的时间根据版本情况定,最终目标是:第一个阶段拿到交付范围,在第五个阶段都完成,并拿到本次版本团队所消耗的工时. Jira是项目过程管理的一种手段,跟多体现在工时跟踪, ...

  4. 文件的上传(如何兼容火狐与IE)与国际化的原理

    1.文件的上传     [1] 简介         > 将本地的文件上传到服务器中         > 用户需要通过一个表单将文件上传到服务器中       [2] 表单的设置     ...

  5. WPF中,Combox的SelectedItem属性绑定成功后,未能默认显示上一次选择的结果。

    问题描述: Combox中,设定了绑定对象,但是在第一次进入时却没有显示上次选中的项.      1)查看SelectedItem对应绑定的值,也是有的(启动时,读取上次设置的结果,来初始化界面). ...

  6. SQL Server 2008 R2——以特定符号出现的次数来判断当前内容所在的层次

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  7. Apple Watch的课表应用iOS源码项目

    源码Class-Timetable,小清新风格的课表应用,可以按周或按天显示课表.按天显示时,左右滑动屏幕可以查看前一天或后一天的课表.功能:可以双模式切换(按天显示,按周显示,可以和 Apple W ...

  8. JS中误用/g导致的正则test()无法正确重复执行

    一个简单的利用正则判断输入是否为数字: input1 = '0281234567';input2 = '0282345678';var reg = /^\d+$/g; reg.test(input1) ...

  9. 3、DNS服务器功能(正向、反向解析)

    实验目的: 建立gr.org域的主名称服务器.解析: 名称 IP 用途 ns.gr.org        192.168.170.3          名称服务器 www.gr.org     192 ...

  10. Web报表工具FineReport的JS API开发(一)

    很多报表软件可以利用JS接口来实现更多更复杂的功能.以FineReport为例,开放了大量的JS API给用户,根据执行JS的主体不同可以将分为三大类:FR.FS和contentWindow. 在js ...