读书人

LINQ查询表达式-学习linq的文件和笔记

发布时间: 2012-12-25 16:18:28 作者: rapoo

LINQ查询表达式--学习linq的资料和笔记(三)

中高级.net程序员群 web方向为主,北京地区 不定期聚会,实名QQ群:249993094

进群的问题为:类的属性的本质是什么?

没有标准答案 全靠自己的理解回答 !


以下文章摘自博客园life a poem 的博客;

书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询表达式(Query Expression)。

LINQ方法语法的本质是通过扩展方法和Lambda表达式来创建查询。C# 3.0对于LINQ表达式还引入了声明式的查询表达式,也叫查询语法,通常来讲,它是创建LINQ查询的更加快捷的方式。尽管通过查询语法写出的查询比较类似于SQL查询,但实际上查询表达式的产生并不是建立在SQL之上,而是建立在函数式编程语言如LISP和Haskell中的list comprehensions(列表解析)功能之上。本篇会对LINQ查询语法进行详细的介绍。

我们在前一篇LINAQ方法语法中所举的示例:获取所有包含字母”a”的姓名,按长度排序并将结果转为大写。下面是与之等价的查询表达式语法:

LINQ查询表达式-学习linq的文件和笔记(三)
        static void Main(string[] args)
{
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> query =
from n in names
where n.Contains("a") // Filter elements
orderby n n.Length // Sort elements, (orderby n 改为 orderby n.Length, 感谢网友搏击的小船发现该处错误)
select n.ToUpper(); // Translate each element

foreach (string name in query)
Console.WriteLine(name);
}
LINQ查询表达式-学习linq的文件和笔记(三)

查询表达式总是以from子句开始,以select或者group子句结束。From子句定义了查询的范围变量(range variable),可以认为该变量是对输入sequence的一个遍历,就像foreach做的那样。下面这幅图描述了查询表达式的完整语法:

LINQ查询表达式-学习linq的文件和笔记(三)

当然,.NET公共语言运行库(CLR)并不具有查询语法的概念。编译器会在程序编译时把查询表达式转换为方法语法,即对扩展方法的调用。这意味着,我们用查询表达式写出来的LINQ查询都有等价的方法语法。对于上例中的查询表达式,编译器会转换成下面的方法语法:

            IEnumerable<string> query = names
.Where (n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select (n => n.ToUpper());

然后,应用编译器对于方法语法的处理规则,上面的Where, OrderBy, Select查询运算符会绑定到Enumerable类中的相应扩展方法。

范围变量

范围变量是紧随from关键字之后定义的变量,一个范围变量指向当前操作符所对应的输入sequence中的当前元素。在我们的示例中,范围变量出现在每一个查询子句中,但要注意的是,变量实际是对不同sequence的遍历,因为Where、OrderBy、Select会有不同的输入sequence:

            IEnumerable<string> query =
from n in names //n是我们定义的范围变量
where n.Contains("a") //n直接来自names array
orderby n.Length //n来自filter之后的subsequent
select n.ToUpper(); //n来自OrderBy之后的subsequent

当 编译器把上面的查询语法翻译成方法语法后,我们会更清楚的看到范围变量的这种行为:

            IEnumerable<string> query2 = names
.Where(n => n.Contains("a")) //n直接来自names array
.OrderBy(n => n.Length) //n来自filter之后的subsequent
.Select(n => n.ToUpper()); //n来自OrderBy之后的subsequent

除了from关键字后面的范围变量,查询表达式还允许我们通过下面的子句引入新的范围变量:

读书人网 >.NET

热点推荐