在几个月之前,.NET社区到处充斥了LINQ to SQL已死的言论,导致很多朋友也不愿意去学习LINQ to SQL,甚至于混淆概念,认为不该学习LINQ,为此我曾经也写过一篇文章不得不为LINQ说几句话,驳“LINQ已死”论来解释过这个问题。几个月过去了,LINQ to SQL不但没死,反而在.NET 4.0中有了很大的变化,尽管微软强调会把数据访问的重心放在Entity Framework上,但是LINQ to SQL的也没有停滞不前。微软Data Programmability项目组的Damien Guard在自己的Blog上发表文章阐述了.NET Framework 4.0中LINQ to SQL的一些变化:
1. 性能
通过特别定义的文本参数长度,查询计划的重用将更为频繁
利用主键在ID缓存中对单条记录的查找,目前包括query.Where(predicate).Single/SingleOrDefault/First/FirstOrDefaul
在指定DataLoadOptions时减少对查询的执行(对beta1版本,在缓存中的查询同样会考虑DataLoadOptions的值)
2. 可用性
ITable接口为实现仿对象提供支持
根据列的类型可以将枚举类型自动转换为int或string类型
在关联的另一端可以指定非主键列,以支持数据的更新
支持查询时列表的初始化语法
LinqDataSource目前可以支持继承的实体
LinqDataSource支持增加的动态数据查询扩展器(Dynamic Data Query extenders)
3. 查询稳定性
Queries that contain sub-queries with scalar projections now work better
现在增加了对自引用IQueryable的检测,不会导致堆栈溢出
Skip(0)目前允许贪婪加载(eager loading)[译注:贪婪加载是数据查询的一种优化措施,在查询时将被查询实体的关联实体均查询出来。]
GetCommand可以对SQL Compact事务进行操作
属性或字段暴露的连接可以被准确地检测并通知
编译后的查询可以准确地检测映射源的变化并抛出
String.StartsWith,EndsWith和Contain目前可以正确地处理“~ in”搜索字符串
能够更好地检测多活动结果集(multiple active result sets, MARS)[译注:MARS是ADO.NET 2.0增加的新功能,允许在同一个数据库连接上处理多个活动的结果集,很好地支持了异步进程处理]
在表值函数(Table-Valued Functions,TVFs)中使用贪婪加载时,能够适当地创建实体间的关系
更好地支持包含了标量投影(scalar projections)子查询的查询
4. 更新稳定性
SubmitChanges不再使用事务回滚异常
在变更冲突的场景下,SubmitChanges能够正确地处理时间戳
IsDbGenerated属性可以被重命名,而不再要求必须与对应的列名匹配
支持服务器生成的列以及SQL复制/触发器,而不再是抛出SQL异常
5.通用稳定性
Binary类型能够正确地被反序列化
当添加一个数据项到未加载的实体集时,会触发EntitySet.ListChanged事件
连接会在释放上下文时被释放
6. SQL要素
外键属性设置器可以检查所有影响到的关系,而不仅限于第一次
在不支持主键类型的情况下对错误处理进行了改善
忽略包含表值参数的存储过程,而不是终止该过程
在出现未知数据类型时不会受到破坏
7. LINQ to SQL设计器
可以处理在SQL结果集中单个的匿名列
改进了在与允许为空的唯一标识列建立关联时的错误消息
允许添加using语句到partial user类
VarChar(1)可以被正确地映射为string而不是char
在存储过程中,DbType特性可以正确地反映Decimal类型的精度与范围
在将表放回到设计器中时,不需要重启就能够反映外键的改变
8. 代码生成
ForeignKeyReferenceAlreadyHasValueException is now thrown if any association is loaded not just the first
在实体和上下文的命名空间不一致时,使用初值的存储过程可以通过编译
内部的Virtual能够生成正确的语法
Mapping特性可以完全避免用户类型的冲突
KnownTypeAttributes可以反映包含继承的DataContractSerializer
保证了延迟加载外键的正确性,以及它的可编译性和代码生成
并发地使用存储过程不再考虑实体是否处于不同的命名空间
如果关联并非第一次加载,就会抛出ForeignKeyReferenceAlreadyHasValueException异常
英文:http://damieng.com/blog/2009/06/01/linq-to-sql-changes-in-net-40
中文:http://www.infoq.com/cn/news/2009/06/DLINQ-4