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. 项目管理过程组和知识领域表(PMBOK2008)

    项目管理过程组和知识领域表(PMBOK2008) 知识领域 项目管理过程组 启动过程组 规划过程组 执行过程组 监控过程组 收尾过程组  4. 项目整合管理 4.1 制定项目章程 4.2 制定项目管理 ...

  2. Ubuntu如何选择更新源

    刚装上Ubuntu, 决定先更新一下源. 虽然网上搜索提供了很多更新源,结果替换上实际使用的时候,却发现总是有404无法连接的情况. 后来查查资料,发现Ubuntu自己就提供了很多的源管理. 具体更新 ...

  3. Provider:SSL Provider,error:0-等待的操作过时

    今天一同事使用SSMS 2012 连接数据库时,遇到了"provider:SSL Provider,error:0-等待的操作过时",搜索了一下,遇到一哥 们也遇到这个问题:SQL ...

  4. CentOS 6编译安装lamp,并分别安装event模块方式和FPM方式的PHP

    任务目标: 编译安装LAMP 要求(1) 安装一个模块化的PHP 要求(2) 安装一个FPM的PHP 注意PHP需要最后一个安装,因为需要前两者的支持. 所以这里的安装次序为 1.httpd 2.Ma ...

  5. 关于Oracle报“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误

    关于Oracle报“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误原因:listener.ora中没有指定监听服务器名. 如下是解决思路: 尝试1.通过重启服务的方式启动数 ...

  6. ElasticSearch集群设置

    多台机器 \config\elasticsearch.yml 文件修改 cluster.name设置统一的集群名如 cluster.name: win-es-001 node.name 设置当前Nod ...

  7. Csharp--Read Csv file to DataTable

    在网上找的资料都不怎么好使,许多代码一看就知道根本没有考虑全面. 最后找到一个好用的,在codeproject上,这位老兄写成了一个framework,太重了. http://www.codeproj ...

  8. 【小白的CFD之旅】14 实例反思

    小白将敲门实例认真做了三遍,终于可以脱离文档直接将实例从头到尾的完成了.不过在做实例的过程中,小白 还是发现了不少的问题. 这些问题包括: 实例是从导入网格文件开始的,这网格是什么鬼? 在Models ...

  9. WPF Freezable–How to improve your application's performances

    在给ImageBrush绑定动态图片是会报以下错误. Error    4    The provided DependencyObject is not a context for this Fre ...

  10. 《InsideUE4》-4-GamePlay架构(三)WorldContext,GameInstance,Engine

    Tags: InsideUE4 UE4深入学习QQ群: 456247757 引言 前文提到说一个World管理多个Level,并负责它们的加载释放.那么,问题来了,一个游戏里是只有一个World吗? ...