.net LINQ and PLINQ
本文 学习自 微软官网文档 2016/12
LINQ 背景
以前写与DB 相关的代码, 程序员须要懂开发语言(C#, VB)和查询语言跟数据库交互。 LINQ 的出现使应用程序形成基于集合的查询。你可以编写针对各种数据源的(实现IEnumerable 接口的数据源)查询 。LINQ适用于内存的数据结构,XML文档,SQL数据库和DataSet对象。
查询是一种从数据源检索数据的表达式。查询通常用专门的查询语言来表示。随着时间的推移,人们已经为各种数据源开发了不同的语言;例如,用于关系数据库的 SQL 和用于 XML 的 XQuery。因此,开发人员不得不针对他们必须支持的每种数据源或数据格式而学习新的查询语言。LINQ 通过提供一种跨各种数据源和数据格式使用数据的一致模型,简化了这一情况。在 LINQ 查询中,始终会用到对象。可以使用相同的基本编码模式来查询和转换 XML 文档、SQL 数据库、ADO.NET 数据集、.NET 集合中的数据以及对其有 LINQ 提供程序可用的任何其他格式的数据。
LINQ 介绍
所有 LINQ 查询操作都由以下三个不同的操作组成:
-
获取数据源。
-
创建查询。
-
执行查询
下图显示了完整的查询操作。在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。
class IntroToLINQ
{
static void Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery =
from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
若要强制立即执行任意查询并缓存其结果,可以调用 ToList<TSource> 或 ToArray<TSource> 方法。
C# 3.0 特性
不必在声明并初始化变量时显式指定类型,您可以使用 var 修饰符来指示编译器推断并分配类型,如下所示:
通过对象和集合初始值设定项,初始化对象时无需为对象显式调用构造函数。初始值设定项通常用在将源数据投影到新数据类型的查询表达式中。假定一个类名为 Customer,具有公共 Name 和 Phone 属性,可以按下列代码中所示使用对象初始值设定项:
Customer cust = new Customer {Name = "Mike" ; Phone ={ "555-1212 "};
匿名类型由编译器构建,且类型名称只可用于编译器。匿名类型提供了一种在查询结果中临时分组一组属性的方便方法,无需定义单独的命名类型。使用新的表达式和对象初始值设定项初始化匿名类型,如下所示:
select new {name = cust.Name, phone = cust.Phone};
通过自动实现的属性,可以更简明地声明属性。当您如下面的示例中所示声明属性时,编译器将创建一个私有的匿名支持字段,该字段只能通过属性 getter 和 setter 进行访问。
public string Name {get; set;}
PLINQ 介绍
并行 LINQ (PLINQ) 是 LINQ 模式的并行实现。 PLINQ 查询在许多方面类似于非并行 LINQ to Objects 查询。 与顺序 LINQ 查询一样,PLINQ 查询对任何内存中 IEnumerable 或 IEnumerable<T> 数据源进行操作,并推迟执行,这意味着在枚举查询之前不会开始执行这些操作。 主要区别是 PLINQ 尝试充分利用系统中的所有处理器。 它利用所有处理器的方法是,将数据源分成片段,然后在多个处理器上对单独工作线程上的每个片段并行执行查询。 在许多情况下,并行执行意味着查询运行速度显著提高。
通过并行执行,PLINQ 通常只需向数据源添加 AsParallel 查询操作,即可在某些查询类型的旧版代码上获得显著的性能改进。 但是,并行可能引入其自己的复杂性,因此并非所有查询操作在 PLINQ 中都运行得更快。 事实上,并行降低了某些查询的速度。 因此,您应了解诸如排序等问题如何影响并行查询。 有关详细信息,请参阅 Understanding Speedup in PLINQ。
PLINQ 的主要用途是通过在多核计算机上以并行方式执行查询委托来加快 LINQ to Objects 查询的执行速度。