c# Linq查询
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查询的更多相关文章
- Entity Framework 6 Recipes 2nd Edition(13-6)译 -> 自动编译的LINQ查询
问题 你想为多次用到的查询提高性能,而且你不想添加额外的编码或配置. 解决方案 假设你有如Figure 13-8 所示的模型 Figure 13-8. A model with an Associat ...
- LinqToDB 源码分析——轻谈Linq查询
LinqToDB框架最大的优势应该是实现了对Linq的支持.如果少了这一个功能相信他在使用上的快感会少了一个层次.本来笔者想要直接讲解LinqToDB框架是如何实现对Linq的支持.写到一半的时候却发 ...
- Linq查询基本操作
摘要:本文介绍Linq查询基本操作(查询关键字) - from 子句 - where 子句 - select子句 - group 子句 - into 子句 - orderby 子句 - join 子句 ...
- C#基础:LINQ 查询函数整理
1.LINQ 函数 1.1.查询结果过滤 :where() Enumerable.Where() 是LINQ 中使用最多的函数,大多数都要针对集合对象进行过滤,因此Where()在LINQ 的操作 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (26) ------ 第五章 加载实体和导航属性之延缓加载关联实体和在别的LINQ查询操作中使用Include()方法
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-7 在别的LINQ查询操作中使用Include()方法 问题 你有一个LINQ ...
- Rafy 中的 Linq 查询支持(根据聚合子条件查询聚合父)
为了提高开发者的易用性,Rafy 领域实体框架在很早开始就已经支持使用 Linq 语法来查询实体了.但是只支持了一些简单的.常用的条件查询,支持的力度很有限.特别是遇到对聚合对象的查询时,就不能再使用 ...
- Linq查询表达式
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...
- .NET LINQ查询操作中的类型关系
LINQ 查询操作中的类型关系 若要有效编写查询,您应该了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果您了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. 另外 ...
- .NET LINQ查询语法与方法语法
LINQ 查询语法与方法语法 通过使用 C# 3.0 中引入的声明性查询语法,介绍性 LINQ 文档中的多数查询都被编写为查询表达式. 但是,.NET 公共语言运行时 (CLR) 本身并不具 ...
随机推荐
- 【强烈推荐】XCODE的插件之王
有许多关于Xcode的插件,在这里强烈推荐的是Alcatraz插件.因为我们可以通过这个插件来安装其他插件 1.Alcatraz插件. Alcatraz是一个方便我们安装各种那个插件的插件.插件之王? ...
- Android中的HTTP通信
前言:近期在慕课网学习了慕课网课程Android中的HTTP通信,就自己总结了一下,其中参考了不少博文,感谢大家的分享. 文章内容包括:1.HTTP简介2.HTTP/1.0和HTTP/1.1之间的区别 ...
- 基于Ruby的Watir-WebDriver自动化测试框架
基于Ruby的watir-webdriver自动化测试方案与实施(五) 基于Ruby的watir-webdriver自动化测试方案与实施(四) 基于Ruby的watir-webdriver自动 ...
- ORACLE数据库SQL语句的执行过程
SQL语句在数据库中处理过程是怎样的呢?执行顺序呢?在回答这个问题前,我们先来回顾一下:在ORACLE数据库系统架构下,SQL语句由用户进程产生,然后传到相对应的服务端进程,之后由服务器进程执行该SQ ...
- 如何让Log4net日志文件按每月归成一个文件夹,StaticLogFileName参数的用法
想要让Log4net日志(以下称日志)按每月自动归类为一个文件夹,为此,学习和修改了log4net.config文件.查了资料,重点是以下这些参数: <param name=" ...
- SQLite学习笔记(九)&&pager模块
概述 通过上一篇文章的分析,我们知道了pager模块在整个sqlite中所处的位置.它是sqlite的核心模块,充当了多种重要角色.作为一个事务管理器,它通过并发控制和故障恢复实现事务的ACID特性, ...
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path解决方案
0.环境: win7系统,Tomcat9配置无误. 1.错误: 项目中某一.jps页面忽然出现错误,鼠标点上去为:The superclass "javax.servlet.http.Htt ...
- CentOS 7 虚拟机无法开机问题
若虚拟机在不正常关机的时候会遇到如下图所示的问题:先点击"取消"按钮
- WPF 自定义CheckBox
WPF中原始的CheckBox样式很简单,有时候不适用于WPF那种炫酷的界面. 本章节讲述如何设计一个匹配业务需要.好看的CheckBox(继上篇<WPF-自定义ListBox>中的Che ...
- ubuntu kylin 14.04编译openjdk-7u40
1.ubuntu kylin 14.04安装依赖 sudo apt-get install build-essential gawk m4 libasound2-dev libcups2-dev li ...