C#高级特性之LINQ(语言集成查询)
什么是linq, 它解决了什么问题
在工程中我们少不了要定义类或者结构去储存数据,这些数据将被临时地储存在内存中,现在我们想要对其完成一些类似于查找、过滤等等常见的任务的时候,我们该如何去做呢? 以前我们可以自己写代码去对集合中的每个对象进行遍历,检查变量的每个字段看其是否满足条件。
LINQ(Language Integrated Query)即语言集成查询, linq可以像SQL一样用来从对象集合/SQL数据库/XML
中查询想要的数据.
自定义类需要实现了IEnumerable或者IEnumerable
LINQ 主要包含以下三部分:
- LINQ to Objects 主要负责对象的查询
- LINQ to XML 主要负责 XML 的查询
- LINQ to ADO.NET(Linq to SQL(少用)/Linq to DataSet/Linq to Entities(重点)) 主要负责数据库的查询,
LINQ 主要解决了什么问题:
面向对象
与数据访问
两个领域长期分裂,各自为政;- 编程语言中的数据类型与数据库中的
数据类型
形成两套体系
,
如:C#中的字符串string 在SQL中使用NVarchar/ Varchar/ Char来表示; - SQL和XML都有各自的查询语言,而
对象没有自己的查询语言
,
例如要从List<>集合或者数组中找到符合要求的元素,非常困难;
linq查询方式
- Linq查询方法, 链式查询方式
list.aaa().bbb().ccc().Select()
- Linq查询语句, 类似SQL的查询语句
from num in listData where num > 100 select num;
大部分的查询语句的关键词都对应查询方法, 例如where语句对应where()方法, select语句对应select()方法等, 当然很多聚合查询(count,max)
方法都还没有对应查询语句, 当然可以先使用查询语句查询出列表后, 再使用聚合方法进行统计也行.
// 查询方法
listData.where(c=>c.num > 100).Count()
// 混合查询 = (查询语句+查询方法)
(from num in listData where num > 100 select num).Count()
LINQ查询方法详解
标准查询操作符 | 说明 |
---|---|
where OfType |
筛选操作符定义了返回元素的条件。在Where查询操作符中,可以使用谓词,例如Lambda表达式定义的谓词,来返回布尔值。OfType |
Select 和SelectMany |
投射操作符用于把对象转换为另一个类型的新对象。Select和SelectMany定义了根据选择器函数选择结果值的投射。 |
OrderBy 、ThenBy 、OrderByDescending 、ThenByDescending 、Reverse |
排序操作符改变所返回的元素的顺序。OrderBy按升序排列,OrderByDescending按降序排列。如果第一次排序结果很类似,就可以使用ThenBy和ThenByDescending操作符进行第二次排序。Reverse反转集合中的元素顺序。 |
GroupBy 、ToLookUp |
组合运算符把数据放在组里面。GroupBy操作符组合有公共键的元素。ToLookUp通过创建一个一对多的字典,来组合元素。 |
Join 、GroupJoin |
链接运算符用于合并不直接相关的集合。使用Join操作符,可以根绝键选择器函数连接两个集合,这类似于SQL中的Join。GroupJoin操作符连接两个集合,组合其结果。 |
Any、All、Contains | 如果元素序列满足指定的条件,两次操作符就返回布尔值。Any、ALll和Contains都是限定符操作符。Any确定集合中是否有确定满足谓词函数的元素。ALll确定集合中的所有元素是否都满足谓词函数。Contains检查某个元素是否在集合中。这些操作符都返回一个布尔值。 |
Take 、Skip 、TakeWhile、SkipWhile |
分区操作符返回集合的一个子集,Take、Skip、TakeWhile、SkipWhile都是分区操作符。使用它们可以得到部分结果,使用Take必须指定要从集合中提取的元素个数;Skip跳过指定个数的元素,提取其它元素;TakeWhile提取条件为真的元素。 |
Distinct、Union、Intersect、Except、Zip | Set操作符返回一个集合。Distinct从集合中删除重复的元素,除了Distinct之外,其它的Set操作符都需要两个集合。Union返回出现在其中一个集合中的唯一元素。Intersect返回两个集合中都有的元素。Except返回值出现在一个集合中的元素。Zip是.NET 4新增的,它把两个集合合并为一个。 |
First、FirstOrDefault、Last、LastOrDefault、ElementAt 、ElementAtOrDefault、Single、SingleOrDefault |
这些元素操作符仅返回一个元素。First返回第一个满足条件的元素。FirstOrDefault类似于First,单如果没有找到满足条件的元素,就返回类型的默认值。Last返回最后一个满足条件的元素。ElementAt指定了要返回的元素的位置。Single只返回一个满足条件的元素。如果有多个元素都满足条件,就抛出一个异常。 |
Count 、Sum 、Min 、Max 、Average 、Aggregate |
聚合操作符计算集合的一个值。利用这些聚合操作符,可以计算所有值的总和、所有元素的个数、值最大和最小的元素,以及平均值等等。 |
ToArray 、ToEnumerable、ToList 、ToDictionary、Cast |
这些转换操作符将集合转换为数组:IEnumerable、IList、IDictionary等。 |
Empty、Range、Repeat | 这些生成操作符返回一个心机和。使用Empty时集合是空的;Range返回一系列数字;Repeat返回一个始终重复一个值的集合。 |
LINQ查询语句详解
LINQ查询表达式以from子句开始,以select/group子句结束。在这两个子句之间可以跟零个或者多个from、let、where、join或者orderby子句。
子句 | 说明 |
---|---|
from |
指定数据源和范围变量(类似于迭代变量)。 |
where |
根据一个或多个由逻辑“与”和逻辑“或”运算符(&& 或 ||)分隔的布尔表达式筛选源元素。 |
select |
指定当执行查询时返回的序列中的元素将具有的类型和形式。 |
group | 按照指定的键值对查询结果进行分组。 |
into | 提供一个标识符,它可以充当对 join、group 或 select 子句的结果的引用。 |
orderby |
基于元素类型的默认比较器按升序或降序对查询结果进行排序。 |
join | 基于两个指定匹配条件之间的相等比较来联接两个数据源。 |
let |
引入一个用于存储查询表达式中的子表达式结果的范围变量。 |
in | join 子句中的上下文关键字。 |
on | join 子句中的上下文关键字。 |
equals | join 子句中的上下文关键字。 |
by | group 子句中的上下文关键字。 |
ascending |
orderby 子句中的上下文关键字。 |
descending |
orderby 子句中的上下文关键字。 |
关于linq的效率问题
linq与普通循环查询的效率对比, 简单查询linq快两倍.
/// <summary>
/// 效率测试
/// </summary>
/// <param name="testCount">第几次测试</param>
private static void timeTest(int testCount)
{
const int listCount = 10000000; // 数组长度
Random random = new Random(); // 数据随机构建值
// 数组构建
List<int> listData = new List<int>();
for (int i = 0; i < listCount; i++)
{
listData.Add(random.Next(10000));
}
// LINQ 测试
Stopwatch linq_Stopwatch = new Stopwatch();
linq_Stopwatch.Start();
var linqList = from num in listData
where num > 100
select num;
var linqCount = linqList.Count();
linq_Stopwatch.Stop();
// 普通方式 测试
Stopwatch before_Stopwatch = new Stopwatch();
before_Stopwatch.Start();
List<int> beforeList = new List<int>(listCount);
for (int i = 0; i < listData.Count(); i++)
{
if (listData[i] > 100)
beforeList.Add(listData[i]);
}
var beforeCount = beforeList.Count;
before_Stopwatch.Stop();
// 打印结果
Console.WriteLine(String.Format("第{0}次测试,测试:{5}条数据。\n\r \t LINQ用时:{1}毫秒,筛选了{2}条数据。\n\r\t 普通用时:{3}毫秒,筛选了{4}条数据。\r\n",
testCount, linq_Stopwatch.ElapsedMilliseconds, linqCount, before_Stopwatch.ElapsedMilliseconds, beforeCount, listCount));
}
扩展阅读
注意:linq为c#语言特性,java是没有这个特性的, 在java8中新增了java OQL
同sql语言
LINQ查询表达式详解(1)
LINQ查询表达式详解(2)
C#进阶之LINQ(1)必备基础知识
C#进阶之LINQ(2)Linq查询语句与查询方法
C# LINQ 详解 From Where Select Group Into OrderBy Let Join
JVM 对象查询语言(OQL)
最后更新于 2022-12-21 14:53:05 并被添加「」标签,已有 784 位童鞋阅读过。
本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处
此处评论已关闭