当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > LINQ学习笔记:复合查询和Lambda表达式语法

ASP.NET
如何使用vb6.0来实现中文实名搜索
C#实现Window管道技术
记录下一些关于测试工具NUNIT的链接资料,有兴趣的朋友也可以跳过去看看
编写与.NET属性窗口交互的RAD组件(自序)
asp.net 关于form认证的一般设置:
编写与.NET属性窗口交互的RAD组件(一)
ActiveX控件的打包发布[无证书发布](一)
Visual SourceSafe 6.0 的问题思考
VB报表输出的问题,恳请不吝赐教
证书和签名--试用微软提供的证书测试工具系列
[dotNET]如何利用ConfigurationSettings.AppSettings.GetValues读取配置文件中多个...
使用C#编写DES加密程序的framework
令你的网页速度大大提高
怎样得到一个系统盘的全名,不是字符,是全名,如:本地磁盘(C:)?
r在richtextbox中插入动画/控件
Code: Writing Text to a File (Visual Basic)
算法讨论:哲学家就餐问题
我们所要关注的是什么?
firebird 连接嵌入式版本
从Csharp走到VB.Net(一):MyClass保留字

ASP.NET 中的 LINQ学习笔记:复合查询和Lambda表达式语法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 101 ::
收藏到网摘: n/a

复合查询

前一节中, 我们写了一个查询来将分解那些包含一个字母a, 按长度排序, 并且最后转换成大写的字符串. 我们还有另外一种复合查询的写法:

 1: //前面我们使用的写法
 2: string[] names = { "James","Jack","Harris"};
 3:  
 4: IEnumerable<string> query = names.Where(n => n.Contains ("a"))
 5: .OrderBy (n => n.Length).Select (n => n.ToUpper( ));
 6:  
 7: //组合查询的写法
 8: string[] names = { "James","Jack","Harris"};
 9: IEnumerable<string> q = from n in names where n.Contains("a")
 10: orderby n.Length
 11: select n.ToUpper();
 12: 
 13: foreach(string s in q)
 14: Console.Write(s + ","); //JACK,JAMES,HARRIS,

 

一个复合查询总是开始于from语句结束于select或者group语句. from语句声明了一个迭代变量, 此变量代表输入序列中的每一个元素, 类似foreach语法中的变量. 编译器会将复合查询翻译成Lambda表达式, 类似于foreach表达式会被翻译成调用GetEnumerator和MoveNext方法. 这意味着任何你可以使用的复合查询同样也可以使用Lambda表达式来完成. 例如上面的例子, 编译器将会翻译成这样:

 1: IEnumerable<string> q = names
 2: .Where(n => n.Contains ("a"))
 3: .OrderBy(n => n.Length)
 4: .Select(n => n.ToUpper());

 

迭代变量

紧跟在from关键字之后的标识符称为迭代变量, 在我们的例子中, 迭代变量n出现在每一个查询中的每一个从句. 然后, 此变量实际上枚举了每一个从句中的不同序列中的元素:

 1: from n in names // n 是我们的迭代变量
 2: where n.Contains ("a") // n = 直接来自于数组
 3: orderby n.Length // n = 被过滤后的
 4: select n.ToUpper(); // n = 排序过的

 

如果检查一下编译器帮我们生成的使用Lambda表达式的版本就可以看得更加清晰一点:

 1: names.Where (n => n.Contains ("a"))
 2: .OrderBy (n => n.Length)
 3: .Select (n => n.ToUpper());

 

n都是只属于各自Lambda表达式的范围里面的.

查询语法 VS SQL语法

LINQ的复合查询语法看起来和SQL语法非常像, 然后他们是非常不同的. 一个LINQ查询说到底还是一个C#表达式, 因为必须要遵循标准的C#规则. 例如, 在LINQ中, 你不能使用一个未声明的变量. 而在SQL中, 在from语句定义之前你已经可以在select中引用一个表的别名了.

在LINQ中的子查询仅仅是另外一个C#表达式, 因此并不需要有什么特殊的语法. 而子查询在SQL当中通常要受到一些特殊规则的限制.

在LINQ中, 整个数据处理流程是从左到右的. 而在SQL中, 这个顺序则更加随机.

一个LINQ查询构成一个传送带, 或者一个管道, 其中的操作符接受和处理有序序列. 而SQL查询则构成的语法网更多的是处理无序集合.

查询语法和 Lambda表达式

复合查询和Lambda表达式语法更有优点. 复合查询对于符合以下情况的查询更加简单一些:

1. let从句来一个迭代变量后用于代表一个新的变量

 1: var list = new List<int>() { 1, 2, 3 };
 2: var query = from i in list
 3: let j = i + 2
 4: let k = j * j
 5: select new { i, j, k };

 

2. SelectMany, Join或者GroupJoin紧跟着一个外部的迭代变量引用

至于Where, OrderBy和Select的使用, 两种表达语法都可以工作的很好, 如何使用, 更多的取决于个人习惯.

对于那些只由单一操作符构成的查询来说, Lambda表达式语法更加简短,简洁一点.

最后, 有很多的操作符是没有对应的复合查询关键字的, 对于这些操作符你只能使用Lambda表达式语法, 或者至少部分使用, 它们是:

Where, Select, SelectManager, OrderBy, ThenBy, OrderByDescending, ThenByDescending, Group, Join, GroupJoin

混合的查询语法

如果一个查询操作符没有对应的复合查询支持, 你可以混合使用复合查询和Lambda表达式语法. 唯一的限制是每一个复合组件都必须被完成(例如从一个form从句开始并且结束于一个select或者group从句).

例如:

 1: string[] names = { "James","Jack","Harris"};
 2: int myCount = (from n in names
 3: where n.Contains ("J")
 4: select n
 5: ).Count();
 6: Console.WriteLine(myCount); //2

 

有一点是非常重要的, 你不能单一的偏向于喜欢复合查询语法或者Lambda表达式语法, 更多的应该是根据功能的需要和简单性来做选择. 待续!