LINQ学习笔记
什么是LINQ
LINQ是C# 3.0的新功能,可以用统一的的语法(类似sql、或者是函数式语言)访问各种数据,包括数据库、XML、对象。
Anders Hejlsberg说LINQ是"It's about turning query set operations and transforms into first-class concepts of the language" (http://channel9.msdn.com/showpost.aspx?postid=114680)。我的感受是:LINQ可以取代SQL,成为一种统一Database、XML世界的查询语言。
举个例子:
var bycity = from p in db.Products
join o in db.Orders
on p.productID equals o.productID
where o.ShipToCity == "Beijing"
select new {o.orderID, p.productName};
foreach (d in bycity) ...
//或者GridView1.DataSource = bycity
这里的db.doctors可以是数据库DataSet,可以是个xml文件,也可以是个List<T>。
所有的新关键字,比如var, from, group, select...都是syntactic sugar。编译器会自动把它翻译成基于Lambda表达式的代码,最后翻译成.net 2.0的程序。var的类型是type inference推断出来的,是强类型的,不等于object;select相当于函数式语言中的Map,当然也支持函数式语言中的Reduce(叫做Aggregate);函数式语言用到的Lambda表达式其实很容易用函数指针delegate实现;最后生成的是一个匿名类型(anonymous type)。
推荐这本小书:LINQ: The Future of Data Access in C# 3.0,只要两小时就看完了。了解一点原理后再用LINQ就方便多了。
LINQ和ASP.net
对ASP.net程序员而言,LINQ主要的应用是用它代替SQL访问数据库。除了不用拼字符串了,一个好处是,LINQ是强类型的,所以用起来更安全。我可以这样写:
var query = db.Orders.Where(o=>o.Description.Contains(txtDescription.Text)); // Contains会被翻译成SQL的LIKE DateTime sinceDate = DateTime.Parse(txtSinceDate.Text); query = query.Where(o=>o.ShipDate > date); // o.ShipDate也是DateTime类型的,所以可以直接比较
Lambda表达式很好用的。
比较麻烦的是,现在有两套数据库访问框架:一个是LINQ to SQL,一个是LINQ to Entity。在用LINQ前,又要花点时间考虑用哪个框架好。
二者对于各种基本CRUD操作有很好的支持。LINQ to SQL可以理解为SQL的替代品,基本上跟SQL能一一对应起来;而LINQ to Entity是2008年8月才推出的,是一个更强大的ORM框架,对多对多关系的支持更好。
举个例子:假设一个表linkProductOrder里只有两列,productID和orderID,用于表达product和order的联系。在LINQ to SQL中这个表会被映射到一个类linkProductOrder,还需要自己写join;而LINQ to Entity中就不会出现这个类,直接用product.Orders和order.Products就可以实现互相访问,完全消除了写join的必要。
我的体会是:LINQ to Entity目前还不够稳定,还是LINQ to SQL保险。用ORM框架的一个问题是,刚开始用时会有lose control的感觉,出了问题完全不知道怎么回事,不像SQL,模型很简单清晰,一个query下去肯定不会出毛病。
我用LINQ to Entity时遇到了几个问题,比如数据库改变后没法重新刷新对象模型,只能删掉对象模型文件重建;还有一次不知道为何新建的对象存不进数据库,这时调试起来非常麻烦。对于复杂的含有多个join的查询,我一般都会先用sql server测试一下,再写成代码;LINQ to Entity不用写join是省了一点事,但是这样反而要在脑子里维护两种模型翻过来译过去。相比之下LINQ to SQL就没出过什么问题。
希望等LINQ to Entity的下个版本出来之后,这种问题会少一些。
总结:不是做广告,C#真的很好很强大。