转自http://blog.csdn.net/qigaopan/article/details/1793840
查询语言LINQ
今天我们开始去认识一下什么是所说的查询语言。其实可能大家有这样的感觉,我们使用面向对象的方式去做数据的操作,有一些不够自然,我们面向对象的方式就是高层的抽象。我们来看一下什么是LINQ:
Class app {
Static void Main(){
String[] names={“Burke”,”Connor”,”Frank”,”Everett”,”Albert”,”Geoege”};
IEnumerable<string> query=from s in names
Where s.length==5
Orderby s
Select s.ToUpper();;
Foreach(string item in query){
console.writeLine(item);
我们看from s in names where….来看很有sql的感觉,但是我们一开始不要直接和sql联系,我们应该从语言底层如何运作来看。其实这里我们要做的是从s中找到字符串长度为5的并且对它们排序转换成大写,最后通过输出方法输出到控制台。我们这里需要强调的就是中间的代码,我们利用传统的方式来做同样的事情,我们也能达到,首先我们找到长度为5的字符串,然后排序,然后转换成大写。从代码量上来考虑,我们可能需要些更多的代码,我们可以仔细的左对比,包括从思维方式上。作为程序员,我们要很好的理解抽象,必须从底层着眼,才能理解的更透彻。
IEnumerable<string> query=from s in names
Where s.length==5
Orderby s
Select s.ToUpper();;
上边的这段代码在语义上等同如下“方法风格的查询”:
IEnumerable<string> query=names.where(s=>s.length==5)
.OrderBy(s=>s)
.Select(s=>s.ToUpper());
如大家看到的一样,其实我们在names上调用方法,我们在字符串数组上掉用方法,wehre方法中的参数就是我们的lambda表达式,后边的orderby和Select方法传递的参数都是lambda表达式。我们可以对上边的那个表达式陌生,但是千万不能对下边的表达式陌生。其实下边的方法风格的查询很容易理解,很符合我们人的思维。
如果我们把lambda表达式继续展开的话,就有如下的委托形式:
Func<string,bool> filter=delegate(string s){return s.Length==5;};
Func<string,string> extract=delegate(string s){ return s;};
Func<string,string> project=delegate(string s){return s.ToUpper();};
IEnumberable<string> query=names.where(filter).
OrderBy(extract)
.Select(project);
这样的形式。实际上便的形式把我们的LINQ给展开了,为了大家能看得比较清楚。也就是需要大家从类似sql语句的形式看到最终展开的委托实力的形式。也就是说我们写的比较自然的语法,在语义上会被转换成方法的调用,很多人可能会问,那里来的这些方法呢?我们的大家都知道数组是没有where或者orderby之类的方法。我们接着讨论。
查询操作符是LINQ中的另外一个重要的设施,LINQ使用扩展方法来定义查询操作符,例如where操作符:
Namespace system.Linq{
Public static class Enumberable{
Public static IEnumberable <T> Where<T> ( this IEnumberable<T> source,Func<T,bool> predicate){
Foreach(T item in source)
If(predicate(item))
Yield return item;
}
}
}
大家注意where方法上加的方法的this关键字,就是我们体验一中的扩展方法的方式。也就是我们为IEnumberable<t>添加了一个新的方法where。那么方法中到底作了什么样的事情,我们看到我们在方法中去找满足predicate委托的item。查询操作符号,指的就是我们这里的where操作符号,也就是我们这里的批predicate委托中的方法。
普通的方式来调用我们的扩展方法就如下:
Ienumberable<string> query=Enumberable.Where(names,s=>Length<6);
现在我们的c#语言允许我们以如下的方式来调用扩展方法:
IEnumberable<string> query=names.Where(s=>s.length<6);
或者
IEnumberable<string> query=from s in names where s.Length<6;
在我们Framework的Linq命名空间下有所有关于LINQ的关键字,其实这些新的技术,就是对我们之前的老技术的从新审视,用一种更加简单的方式来表达之前很复杂的语义。我们不是说LINQ比之前的一些概念有多么的新,其实我们只是对之前的一些东西更加抽象了。其实学习任何一种语言,技术,我们都不可避免的要从抽象和底层两个层次来学习,荒废任何一个方面都会让我们走很多弯路。其实LINQ的出现就是我们在抽象层次的进一步的发展,在数据表达和操作上来讲。从技术上来讲,我们必须了解这样语言机制要表达的意思,更为重要的是我们要理解在语言机制下到底是什么东西。理解底层我们可以更加油效率的去做一些事情,而不是盲目的去做一些事情。任何技术都有它的抽象层次和底层层次,如果我们能把这两个方面整合起来,那么我们肯定能够去把握这门语言的发展趋势,甚至是他的未来。
终极计算机语言可能就是我们人的自然语言,如果计算机能理解人的语言,那么我们这些程序员可能就要失业了。但是技术就是朝着这个方向去发展的,如何去理解这些抽象而不是被这些抽象所蒙蔽,使我们程序员必须认真考虑的地方。