(一)LINQ概述

语言集成查询(Language Integrated Query,LINQ)在C#编程语言中继承了查询语法,可以用相同的语法访问不同的数据源。

1、LINQ查询

var query = from r in Formula1.GetChampions()

            where r.Country == "Brazil"

            orderby r.Wins descending

            select r;

这是一个LINQ查询,子句from、where、orderby、descending和select都是这个查询中预定义的关键字。

2、扩展方法

扩展方法在静态类中声明,定义一个静态方法,其中第一个参数定义了它扩展的类型。

例子:

public static void WriteWithTime(this string message)
{
Console.WriteLine(message + "," + DateTime.Now.ToString("yyyy-MM-dd"));
}

为了和一般的静态方法进行区分,扩展方法还需要对第一个参数使用this关键字。

现在可以使用带string类型的WriteWithTime()方法了。

例子:

string message = "test txt";

message.WriteWithTime();

定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。

例子:

List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };

var maxIntList = intList.Where(i => i > 4);

这里使用Where扩展方法获取大于4的值。

3、推迟查询的执行

在运行期间定义查询表达式时,查询就不会运行。查询会在迭代数据项时进行。

例子:

List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };

var maxIntList = intList.Where(i => i > 4);

foreach (var item in maxIntList)

{

    Console.WriteLine(item);

}

intList.Add(6);

foreach (var item in maxIntList)

{

    Console.WriteLine(item);

}

运行以上代码,结果如下:

需要注意的是,每次在迭代中使用查询时,都会调用扩展方法(可以检测出数据源中的变化)。但调用扩展方法ToArray()、ToList()可以改变这个操作。

例子:

List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };

var maxIntList = intList.Where(i => i > 4).ToList();//调用ToList()方法

foreach (var item in maxIntList)

{

    Console.WriteLine(item);

}

intList.Add(6);

foreach (var item in maxIntList)

{

    Console.WriteLine(item);

}

运行以上代码,结果如下:

(二)标准的查询操作符

参考:http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html

(三)并行LINQ

1、并行查询

例子:

var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };

var res = data.AsParallel().Where(d => d > 2);

调用AsParaller()方法进行LINQ并行查询。

2、分区器

AsParallel()方法不仅扩展了IEnumerable<T>接口,还扩展了System.Collection.Concurrent名称空间的Partitioner类。

例子

var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };

var result = Partitioner.Create(data, true).AsParallel().Where(d => d > 2);

使用Create()方法手工创建一个分区器。

3、取消

.NET提供了一种标准方式,来取消长时间运行的任务,这也适用于并行LINQ。

例子:

var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
var cts = new CancellationTokenSource();
Task.Factory.StartNew(()=> {
try
{
var resu = data.AsParallel().WithCancellation(cts.Token).Where(d => d > 2);
Console.WriteLine("查询结束");
}
catch (OperationCanceledException ex)
{
Console.WriteLine(ex.Message);
throw;
}
});
Console.WriteLine("查询开始");
Console.WriteLine("取消?");
string input = Console.ReadLine();
if (input.ToLower().Equals("y"))
{
cts.Cancel();
}

给并行查询处添加WithCancellation()方法,参数为CancellationToken令牌为参数。当取消查询时会抛出OperationCanceledException类型的异常,捕捉异常后可以使用Cancel()方法取消查询任务。

(四)表达式树

C#编译器根据类型给lambda表达式定义不同的行为,当类型为Expression<T>,编译器就从lambda表达式中创建一个表达式树,并存储在程序集中。

例子:

 1 static void Main(string[] args)
2 {
3 Expression<Func<int, bool>> expression = s => s > 1 ;
4 DisplayTree(0, "lambda", expression);
5 Console.ReadKey();
6 }
7 static void DisplayTree(int indent, string message, Expression expression)
8 {
9 string outPut = string.Format("{0} {1} ! NodeType: {2}; Expr: {3}", "".PadLeft(indent, '>'), message, expression.NodeType, expression);
10 indent++;
11 switch (expression.NodeType)
12 {
13 case ExpressionType.Constant:
14 ConstantExpression constExpr = (ConstantExpression)expression;
15 Console.WriteLine("{0} Const Value: {1}", outPut, constExpr.Value);
16 break;
17 case ExpressionType.Equal:
18 case ExpressionType.AndAlso:
19 case ExpressionType.GreaterThan:
20 BinaryExpression binExpr = (BinaryExpression)expression;
21 if (binExpr.Method != null)
22 {
23 Console.WriteLine("{0} Method: {1}", outPut, binExpr.Method.Name);
24 }
25 else
26 {
27 Console.WriteLine(outPut);
28 }
29 DisplayTree(indent, "Left", binExpr.Left);
30 DisplayTree(indent, "Right", binExpr.Right);
31 break;
32 case ExpressionType.Lambda:
33 Console.WriteLine(outPut);
34 LambdaExpression lambdaExpr = (LambdaExpression)expression;
35 foreach (var item in lambdaExpr.Parameters)
36 {
37 DisplayTree(indent, "Parameter", item);
38 }
39 DisplayTree(indent, "Body", lambdaExpr.Body);
40 break;
41 case ExpressionType.MemberAccess:
42 MemberExpression memberExpr = (MemberExpression)expression;
43 Console.WriteLine("{0} Member Name: {1}, Type: {2}", outPut, memberExpr.Member.Name, memberExpr.Type.Name);
44 DisplayTree(indent, "Member Expr", memberExpr.Expression);
45 break;
46 case ExpressionType.Parameter:
47 ParameterExpression parameExpr = (ParameterExpression)expression;
48 Console.WriteLine("{0} Param Type: {1}", outPut, parameExpr.Type.Name);
49 break;
50 default:
51 Console.WriteLine();
52 Console.WriteLine("{0} {1}", expression.NodeType, expression.Type.Name);
53 break;
54 }
55 }

最新文章

  1. 怎样给Myeclipse配置tomcat服务器
  2. chrome (failed) net::ERR_INCOMPLETE_CHUNKED_ENCODING ashx 加载图片
  3. IntelliJ IDEA 使用说明(For Eclipse user)
  4. JavaScript 产生指定范围随机数
  5. windows下C语言编程获取磁盘(分区)使用情况
  6. 分享10 个超酷的 HTML5/CSS3 应用及源码
  7. 确认某端口占用情况并结束相应进程(Windows)
  8. Delphi开发ocx插件的调试
  9. validate插件深入篇
  10. vagrant打造自己的开发环境
  11. virtual box ubuntu 与Windows共享文件夹
  12. Ubuntu TensorFlow 源码 Android Demo的编译运行
  13. Eclipse的Servers视图中无法加入Tomcat6/Tomcat7
  14. Django+xadmin打造在线教育平台(十)
  15. 【MySQL】MySQL内连接,左连接,右连接查询
  16. 模板引擎ejs入门学习
  17. nodejs 中的一些方法
  18. Image.fromarray的用法
  19. Redis 学习手册
  20. 邮件发送 utils

热门文章

  1. python小题目练习(二)
  2. Min-max 容斥与 kth 容斥
  3. nw.js的cookie操作
  4. 项目中使用@Transactional需要注意的点
  5. vue2升级vue3指南(一)—— 环境准备和构建篇
  6. cx_Oracle.DatabaseError: ORA-28759: failure to open file
  7. 如何用车辆违章查询API接口进行快速开发
  8. 基于yarn1.x的monorepo实践分享
  9. C++ 加速(卡常)技巧【超级 快读、快写】
  10. CSDN垃圾的没有底线!